多指令[ngController,...]要求新/隔离范围

时间:2016-04-22 14:11:08

标签: angularjs

我有以下(https://jsfiddle.net/hhgqup4f/5/):

import UIKit

class BoldLabel: UILabel {
    override internal var font: UIFont? {
        get {
            return UIFont.boldSystemFontOfSize(16.0)
        }
    }
}

控制器是:

<div parent parent-model="vm.model1" ng-controller="Controller as vm">
   Parent
</div>

然后我有一个如下指令:

app.controller("Controller", Controller);

function Controller() {
  var vm = this;
  vm.model1 = "My Model 1";
  vm.model2 = "My Model 2";
}

使用parent-model =“vm.model1”我试图说明指令应该使用控制器中的哪个属性。但是当我在指令中执行console.log($ scope.model)时,我得到错误:

app.directive("parent", parent);

function parent() {

  var parent = {
    controller: ["$scope", controller],
    replace: false,
    restrict: "A",
    scope: {
      model: "="
    }
  };

  return parent;

  function controller($scope) { 
    console.log($scope.model);
  } 

}  

如何解决这个问题?

1 个答案:

答案 0 :(得分:11)

错误......

  

"Error: [$compile:multidir] Multiple directives [ngController, parent (module: app)] asking for new/isolated scope on: <div parent="" parent-model="vm.model1" ng-controller="Controller as vm">

...非常具有说明性,因为AngularJS不允许多个指令(在相同的DOM级别上)创建自己的 isolate 范围。

根据documentation,此限制是为了防止$scope对象的冲突或不受支持的配置

通常情况下,指令提供隔离scope,其目的是组件化重用附加到DOM的某些逻辑/操作。

因此,有意义的是,两个可重用的组件不能合并在一起以产生组合效果(至少在AngularJS中)。

解决方案

更改您的指令用法,使其提供,并使用其直接父级所需的属性(,在本例中为ngController指令)。< / p>

<div ng-controller="Controller as vm">
  <div parent parent-model="vm.model1"></div>
</div>

同样,您可以以规范化格式访问传递的属性到指令的隔离范围:

app.directive('parent', function(){
  return {
    scope: {
       parentModel: '='  // property passed from the parent scope
    },
    controller: function($scope){
       console.log($scope.parentModel); 
    }
  };
});

Demo

指令传播指令

如前所述,两个或多个带隔离范围的指令不能在同一个DOM元素上使用。但是,其中一个指令可能具有独立的范围。在这种情况下,其他指令可以在 require 其控制器的情况下进行通信:

<div dir-isolate dir-sibling></div>

...

.directive('dirIsolate', function(){
  return {
    scope: {},
    controller: function(){
      this.askSomething = function(){
         return 'Did you ask for something?';
      };
    }
  };
})
.directive('dirSibling', function(){
  return {
    require: 'dirIsolate', // here is the trick
    link: function(scope, iElement, attrs, dirSiblingCtrl){ // required controller passed to the link function as fourth argument
       console.log(dirSiblingCtrl.askSomething());
    }
  };
});