如何将字符串和布尔变量自动传递给指令父范围
How to pass string and bool variables automatically to directive parent scope
我在这样的指令中绑定变量:
<path-filter-modal is-opened="filterModalIsOpened">
并且在指令中我使用“=”绑定,如下所示:
scope: {
isOpened: '='
}
当我在指令中更改变量时,父作用域包含自己的值。
如何使父作用域包含相同的值?
对于对象,它工作得很好,但不适用于字符串和布尔值。
请注意,我在指令中使用指令中定义的控制器来更改值。
因为JavaScript就是这么设计的
在指令中定义隔离作用域会创建一个新的 $scope
对象,它是一个单独的 $scope
对象。它与父范围的唯一关系是:$isolateScope.$parent === $parentScope
。 它不继承自 $parentScope
原型。
当您将一些原始类型 (string/boolean) 分配给 $scope.isOpened
时,实际上 JavaScript 引擎将创建一个 new $scope
上的变量 isOpened
。和$parentScope.isOpened
.
完全没有关系
但是现在,Angular 会隐式地为您同步这两个变量。所以绑定原始变量仍然使 two-way binding
工作良好。请检查 JSFiddle.
如果绑定到某个对象类型,则子作用域和父作用域将引用内存中对象的完全相同副本。更改父作用域将自动更改子作用域。所以总是建议 two-way binding
绑定对象,而不是原始类型。
检查此 JSFiddle。我将一个原语和一个对象绑定到指令 myDirective
。然后在link
函数里面修改它们:
scope.primitiveParam = 'primitive from directive';
// $parent.primitive and primitiveParam refer to different memory;
// Angular is responsible to sync them.
console.log(scope.$parent.primitive);
console.log(scope.primitiveParam);
scope.objectParam.name = 'object from directive';
// $parent.obj and objectParam refer to an identical object
console.log(scope.$parent.obj.name);
console.log(scope.objectParam.name);
console.log(scope.objectParam === scope.$parent.obj);
结果如下:
primitive from parent
primitive from directive
object from directive
object from directive
更多详情:Understanding Scopes(这里有很多直观的图片清楚地说明了概念)
回复:对于对象它工作得很好但不适用于字符串和布尔值
我认为这是原型继承问题的常见情况。当模型来自对象时效果很好,但如果它来自非对象,则 ng-model 有可能是在子范围内创建的。
要解决该问题,请使用现代方法,使用 Controller as
方法。或者将 filterModelIsOpened 放在一个对象中。第一种方法更好。
<div ng-controller="SomeController as s">
<path-filter-modal is-opened="s.filterModalIsOpened">
</div>
function SomeController() { // no need to use $scope
this.filterModalIsOpened = false;
}
或者,如果您使用的是旧版本 Angular,则无法使用 Controller as
方法。只需在控制器中创建您自己的别名:
<div ng-controller="SomeController">
<path-filter-modal is-opened="s.filterModalIsOpened">
</div>
function SomeController($scope) {
$scope["s"] = this;
this.filterModalIsOpened = false;
}
这里有一篇解释原型继承的好文章:http://codetunnel.io/angularjs-controller-as-or-scope/
以下是为什么您应该 始终 为您的模型添加前缀,无论它们是对象还是原始模型。
不推荐。现场代码演示:http://jsfiddle.net/hdks813z/1/
<div ng-app="App" ng-controller="Ctrl">
<div ng-if="true">
<input type="checkbox" ng-model="filterModalCanBeOpened"/>
<the-directive primitive-param="filterModalCanBeOpened"></the-directive>
</div>
<hr/>
<p>
The value below doesn't react to changes in primitive(non-object) property
that is created a copy on a directive(e.g., ng-repeat, ng-if) that creates
child scope
</p>
$scope.primitive: {{filterModalCanBeOpened}}
</div>
angular.module('App', [])
.directive('theDirective', function () {
return {
restrict: 'AE',
scope: {
primitiveParam: '='
},
template: '<div>primitiveParam from directive: {{ primitiveParam }}; </div>',
link: function (scope) {
}
};
})
.controller('Ctrl', ['$scope', function ($scope) {
$scope.filterModalCanBeOpened = true;
}]);
推荐:实时代码演示:http://jsfiddle.net/2rpv27kt/
<div ng-app="App" ng-controller="Ctrl as c">
<div ng-if="true">
<input type="checkbox" ng-model="c.filterModalCanBeOpened"/>
<the-directive primitive-param="c.filterModalCanBeOpened"></the-directive>
</div>
<hr/>
<p>
The value below react to changes in primitive(non-object) property that is
addressed directly by its alias c, creating child scope on it would be
impossible. So the primitive below react to changes on
the c's filterModalCanBeOpened.
</p>
c.primitive: {{c.filterModalCanBeOpened}}
</div>
angular.module('App', [])
.directive('theDirective', function () {
return {
restrict: 'AE',
scope: {
primitiveParam: '='
},
template: '<div>primitiveParam from directive: {{ primitiveParam }}; </div>',
link: function (scope) {
}
};
})
.controller('Ctrl', [function () {
this.filterModalCanBeOpened = true;
}]);
我在这样的指令中绑定变量:
<path-filter-modal is-opened="filterModalIsOpened">
并且在指令中我使用“=”绑定,如下所示:
scope: {
isOpened: '='
}
当我在指令中更改变量时,父作用域包含自己的值。 如何使父作用域包含相同的值?
对于对象,它工作得很好,但不适用于字符串和布尔值。 请注意,我在指令中使用指令中定义的控制器来更改值。
因为JavaScript就是这么设计的
在指令中定义隔离作用域会创建一个新的 $scope
对象,它是一个单独的 $scope
对象。它与父范围的唯一关系是:$isolateScope.$parent === $parentScope
。 它不继承自 $parentScope
原型。
当您将一些原始类型 (string/boolean) 分配给
完全没有关系$scope.isOpened
时,实际上 JavaScript 引擎将创建一个 new$scope
上的变量isOpened
。和$parentScope.isOpened
.但是现在,Angular 会隐式地为您同步这两个变量。所以绑定原始变量仍然使
two-way binding
工作良好。请检查 JSFiddle.如果绑定到某个对象类型,则子作用域和父作用域将引用内存中对象的完全相同副本。更改父作用域将自动更改子作用域。所以总是建议
two-way binding
绑定对象,而不是原始类型。
检查此 JSFiddle。我将一个原语和一个对象绑定到指令 myDirective
。然后在link
函数里面修改它们:
scope.primitiveParam = 'primitive from directive';
// $parent.primitive and primitiveParam refer to different memory;
// Angular is responsible to sync them.
console.log(scope.$parent.primitive);
console.log(scope.primitiveParam);
scope.objectParam.name = 'object from directive';
// $parent.obj and objectParam refer to an identical object
console.log(scope.$parent.obj.name);
console.log(scope.objectParam.name);
console.log(scope.objectParam === scope.$parent.obj);
结果如下:
primitive from parent
primitive from directive
object from directive
object from directive
更多详情:Understanding Scopes(这里有很多直观的图片清楚地说明了概念)
回复:对于对象它工作得很好但不适用于字符串和布尔值
我认为这是原型继承问题的常见情况。当模型来自对象时效果很好,但如果它来自非对象,则 ng-model 有可能是在子范围内创建的。
要解决该问题,请使用现代方法,使用 Controller as
方法。或者将 filterModelIsOpened 放在一个对象中。第一种方法更好。
<div ng-controller="SomeController as s">
<path-filter-modal is-opened="s.filterModalIsOpened">
</div>
function SomeController() { // no need to use $scope
this.filterModalIsOpened = false;
}
或者,如果您使用的是旧版本 Angular,则无法使用 Controller as
方法。只需在控制器中创建您自己的别名:
<div ng-controller="SomeController">
<path-filter-modal is-opened="s.filterModalIsOpened">
</div>
function SomeController($scope) {
$scope["s"] = this;
this.filterModalIsOpened = false;
}
这里有一篇解释原型继承的好文章:http://codetunnel.io/angularjs-controller-as-or-scope/
以下是为什么您应该 始终 为您的模型添加前缀,无论它们是对象还是原始模型。
不推荐。现场代码演示:http://jsfiddle.net/hdks813z/1/
<div ng-app="App" ng-controller="Ctrl">
<div ng-if="true">
<input type="checkbox" ng-model="filterModalCanBeOpened"/>
<the-directive primitive-param="filterModalCanBeOpened"></the-directive>
</div>
<hr/>
<p>
The value below doesn't react to changes in primitive(non-object) property
that is created a copy on a directive(e.g., ng-repeat, ng-if) that creates
child scope
</p>
$scope.primitive: {{filterModalCanBeOpened}}
</div>
angular.module('App', [])
.directive('theDirective', function () {
return {
restrict: 'AE',
scope: {
primitiveParam: '='
},
template: '<div>primitiveParam from directive: {{ primitiveParam }}; </div>',
link: function (scope) {
}
};
})
.controller('Ctrl', ['$scope', function ($scope) {
$scope.filterModalCanBeOpened = true;
}]);
推荐:实时代码演示:http://jsfiddle.net/2rpv27kt/
<div ng-app="App" ng-controller="Ctrl as c">
<div ng-if="true">
<input type="checkbox" ng-model="c.filterModalCanBeOpened"/>
<the-directive primitive-param="c.filterModalCanBeOpened"></the-directive>
</div>
<hr/>
<p>
The value below react to changes in primitive(non-object) property that is
addressed directly by its alias c, creating child scope on it would be
impossible. So the primitive below react to changes on
the c's filterModalCanBeOpened.
</p>
c.primitive: {{c.filterModalCanBeOpened}}
</div>
angular.module('App', [])
.directive('theDirective', function () {
return {
restrict: 'AE',
scope: {
primitiveParam: '='
},
template: '<div>primitiveParam from directive: {{ primitiveParam }}; </div>',
link: function (scope) {
}
};
})
.controller('Ctrl', [function () {
this.filterModalCanBeOpened = true;
}]);