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

时间:2013-03-21 22:31:28

标签: angularjs angularjs-scope

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

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

标题由呼叫控制器提供,并按如下方式应用

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

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

AlertFactory.open($scope);

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

谢谢。

5 个答案:

答案 0 :(得分:103)

您可以手动创建新范围。

如果你注射它,你可以从$rootScope创建一个新的范围,或者只是从你的控制器范围创建一个新的范围 - 这应该不重要,因为你将它隔离开来。

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

AlertFactory.open(alertScope);

此处的关键是将true传递给$newisolate接受{{1}}的一个参数,这样可以避免从父级继承范围。

更多信息可在以下网址找到: http://docs.angularjs.org/api/ng.$rootScope.Scope#$new

答案 1 :(得分:21)

如果您只需要插入内容,请使用$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
        }
    }
});

测试控制器:

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

Fiddle

答案 2 :(得分:2)

以下是步骤:

  1. 使用var comiledHTML = angular.element(yourHTML);
  2. 将您的HTML添加到DOM
  3. 如果您需要var newScope = $rootScope.$new();
  4. ,请创建新的范围
  5. 调用$ comile();返回链接函数var linkFun = $compile(comiledHTML);
  6. 的函数
  7. 通过调用linkFun var finalTemplate = linkFun(newScope);
  8. 绑定新范围
  9. 将finalTemplate附加到DOM YourHTMLElemet.append(finalTemplate);

答案 3 :(得分:2)

看看我的傻瓜。我以编程方式使用render指令生成一个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);
    }
  }
}

答案 4 :(得分:1)

我假设当你在讨论隔离范围时,你正在谈论指令。

以下是如何操作的示例。 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,您可以将隔离范围传递给。