AngularJS-如何以编程方式创建一个新的、独立的作用域?

我想用 Angular.Factory 创建一个 AlertFactory。 我定义了一个如下的 html 模板

var template = "<h1>{{title}}</h1>";

标题由调用控制器提供,应用如下

var compiled = $compile(template)(scope);
body.append(compiled);

那么,如何将隔离作用域从控制器传递到工厂呢? 我在控制器中使用的跟随代码

AlertFactory.open($scope);

但是 $scope 是全局控制器范围变量。

谢谢你。

56737 次浏览

您可以手动创建一个新范围。

您可以从 $rootScope中创建一个新作用域,如果您注入了它,或者仅仅从您的控制器作用域中创建一个新作用域——这应该没有关系,因为您将使它被隔离。

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


AlertFactory.open(alertScope);

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

详情请浏览: Http://docs.angularjs.org/api/ng.$rootscope ,范围 # $新

我假设当你在谈论一个独立的范围时,你是在谈论一个指令。

这里有一个如何做的例子。 Http://jsfiddle.net/rgaskill/pyhgb/

var app = angular.module('test',[]);


app.controller('TestCtrl', function ($scope) {
$scope.val = 'World';
});


app.factory('AlertFactory', function () {


return {
doWork: function(scope) {
scope.title = 'Fun';
//scope.title = scope.val;  //notice val doesn't exist in this scope
}
};


});


app.controller('DirCtrl', function ($scope, AlertFactory) {
AlertFactory.doWork($scope);
});


app.directive('titleVal',function () {
return {
template: '<h1>Hello \{\{title}}</h1>',
restrict: 'E',
controller: 'DirCtrl',
scope: {
title: '='
},
link: function() {


}
};


});

基本上,将控制器附加到定义了隔离作用域的指令。注入到指令控制器中的作用域将是一个独立作用域。在指令控制器中,可以将 AlertFactory 注入到隔离作用域中。

如果您只需要插入内容,那么使用 $插入服务而不是 $edit,这样您就不需要范围:

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
}
}
});

测试控制器:

function MyCtrl($scope, myService) {
myService.open('The Title');
}

小提琴

以下是步骤:

  1. 使用 < code > var comiledHTML = 将 HTML 添加到 DOM Element (yourHTML) ;
  2. 创建一个新的范围,如果你想 var newScope = $rootScope.$new();
  3. 调用 $comile () ; 函数返回 link 函数 < code > var linkFun = 编译(comiledHTML) ;
  4. 通过调用 linkFun < code > var finalTemplate = 绑定新范围 LinkFun (newScope) ;
  5. 将 finalTemplate 附加到 DOM YourHTMLElemet.append(finalTemplate);

看看我的 plunkr,我正在通过编程生成一个带有渲染指令的 widget 指令。

Https://plnkr.co/edit/5t642u9aipr6fjthbvpd?p=preview

angular
.module('app', [])
.controller('mainCtrl', $scope => $scope.x = 'test')
.directive('widget', widget)
.directive('render', render)


function widget() {
return {
template: '<div><input ng-model="stuff"/>I say \{\{stuff}}</div>'
}
}


function render($compile) {
return {
template: '<button ng-click="add()">\{\{name}}</button><hr/>',
link: linkFn
}


function linkFn(scope, elem, attr) {
scope.name = 'Add Widget';
scope.add = () => {
const newScope = scope.$new(true);
newScope.export = (data) => alert(data);
const templ = '<div>' +
'<widget></widget>' +
'<button ng-click="export(this.stuff)">Export</button>' +
'</div>';
const compiledTempl = $compile(templ)(newScope);
elem.append(compiledTempl);
}
}
}