AngularJS - 如何以编程方式创建新的隔离范围?

Pre*_*ier 80 angularjs angularjs-scope

我想用Angular.factory创建一个AlertFactory.我定义了一个html模板,如下

var template = "<h1>{{title}}</h1>";
Run Code Online (Sandbox Code Playgroud)

标题由呼叫控制器提供并应用如下

var compiled = $compile(template)(scope);
body.append(compiled);
Run Code Online (Sandbox Code Playgroud)

那么,我如何将隔离范围从控制器传递到工厂?我正在使用控制器跟随代码

AlertFactory.open($scope);
Run Code Online (Sandbox Code Playgroud)

但$ scope是全局控制器范围变量.我只想通过标题属性传递一个小范围的工厂.

谢谢.

Ale*_*orn 106

您可以手动创建新范围.

你可以创建一个新的范围,$rootScope如果你注入它,或者只是从你的控制器范围 - 这应该无关紧要,因为你将它隔离.

var alertScope = $scope.$new(true);
alertScope.title = 'Hello';

AlertFactory.open(alertScope);
Run Code Online (Sandbox Code Playgroud)

这里的关键是传递true$new,它接受一个参数isolate,这避免了从父级继承范围.

有关更多信息,请访问:http: //docs.angularjs.org/api/ng.$ro​​otScope.Scope#$new

  • 如果手动创建新范围,则可能还需要手动销毁它.通常最好不要手动创建范围. (10认同)
  • 当您创建子范围(隔离或不隔离)时,Angular会在其父节点被销毁时自动销毁它.所以在这个例子中,当`$ scope`被破坏时,"alertScope"也会被自动销毁.所以@MarkRajcok这是一个完全有效的用例,非常安全. (9认同)
  • @MarkRajcok你提到通常最好不要手动创建范围.但是,如果您需要动态创建html并希望在该html中使用angular指令,那么还有什么选择呢? (3认同)

Mar*_*cok 22

如果您只需要插入内容,请使用$ interpolate服务而不是$ compile,然后您将不需要范围:

myApp.factory('myService', function($interpolate) {
    var template = "<h1>{{title}}</h1>";
    var interpolateFn = $interpolate(template);
    return {
        open: function(title) {
            var html = interpolateFn({ title: title });
            console.log(html);
            // append the html somewhere
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

测试控制器:

function MyCtrl($scope, myService) {
    myService.open('The Title');
}
Run Code Online (Sandbox Code Playgroud)

小提琴

  • @Premier,这是我的理解.另请参见http://stackoverflow.com/a/13460295/215945如果您的模板包含指令,那么$ interpolate将不起作用 - 您需要使用$ compile. (3认同)
  • $ compile和$ interpolate有什么区别?$ interpolate只替换文本? (2认同)