从指令到控制器传递AngularJS范围variables的最简单的方法是什么?
将AngularJS范围variables从指令传递给控制器最简单的方法是什么? 我见过的所有例子看起来都非常复杂,是不是有一种方法可以通过指令访问控制器,并设置其中一个范围variables?
2014/8/25编辑: 这是我分叉的地方。
谢谢@anvarik。
这里是JSFiddle 。 我忘了我在哪里分叉。 但这是一个很好的例子,显示了=和@
<div ng-controller="MyCtrl"> <h2>Parent Scope</h2> <input ng-model="foo"> <i>// Update to see how parent scope interacts with component scope</i> <br><br> <!-- attribute-foo binds to a DOM attribute which is always a string. That is why we are wrapping it in curly braces so that it can be interpolated. --> <my-component attribute-foo="{{foo}}" binding-foo="foo" isolated-expression-foo="updateFoo(newFoo)" > <h2>Attribute</h2> <div> <strong>get:</strong> {{isolatedAttributeFoo}} </div> <div> <strong>set:</strong> <input ng-model="isolatedAttributeFoo"> <i>// This does not update the parent scope.</i> </div> <h2>Binding</h2> <div> <strong>get:</strong> {{isolatedBindingFoo}} </div> <div> <strong>set:</strong> <input ng-model="isolatedBindingFoo"> <i>// This does update the parent scope.</i> </div> <h2>Expression</h2> <div> <input ng-model="isolatedFoo"> <button class="btn" ng-click="isolatedExpressionFoo({newFoo:isolatedFoo})">Submit</button> <i>// And this calls a function on the parent scope.</i> </div> </my-component> </div>
var myModule = angular.module('myModule', []) .directive('myComponent', function () { return { restrict:'E', scope:{ /* NOTE: Normally I would set my attributes and bindings to be the same name but I wanted to delineate between parent and isolated scope. */ isolatedAttributeFoo:'@attributeFoo', isolatedBindingFoo:'=bindingFoo', isolatedExpressionFoo:'&' } }; }) .controller('MyCtrl', ['$scope', function ($scope) { $scope.foo = 'Hello!'; $scope.updateFoo = function (newFoo) { $scope.foo = newFoo; } }]);
等到angular度评估variables
我有很多摆弄这个,甚至无法使用范围内的"="
定义的variables工作。 这里有三种解决scheme,取决于你的情况。
解决scheme#1
我发现variables不是通过angular度来评估,而是当它传递给指令时。 这意味着您可以访问它并在模板中使用它,但不能在链接或应用程序控制器function中使用,除非我们等待它被评估。
如果你的variables正在改变 ,或者通过请求获取,你应该使用$observe
或$watch
:
app.directive('yourDirective', function () { return { restrict: 'A', // NB: no isolated scope!! link: function (scope, element, attrs) { // observe changes in attribute - could also be scope.$watch attrs.$observe('yourDirective', function (value) { if (value) { console.log(value); // pass value to app controller scope.variable = value; } }); }, // the variable is available in directive controller, // and can be fetched as done in link function controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) { // observe changes in attribute - could also be scope.$watch $attrs.$observe('yourDirective', function (value) { if (value) { console.log(value); // pass value to app controller $scope.variable = value; } }); } ] }; }) .controller('MyCtrl', ['$scope', function ($scope) { // variable passed to app controller $scope.$watch('variable', function (value) { if (value) { console.log(value); } }); }]);
这里的HTML(记住方括号!):
<div ng-controller="MyCtrl"> <div your-directive="{{ someObject.someVariable }}"></div> <!-- use ng-bind in stead of {{ }}, when you can to avoids FOUC --> <div ng-bind="variable"></div> </div>
请注意,如果使用$observe
函数,则不应在该范围中将该variables设置为"="
。 另外,我发现它将对象作为string传递,因此如果传递对象,请使用解决scheme#2或scope.$watch(attrs.yourDirective, fn)
(或如果variables不变,则为#3 )。
解决scheme#2
如果您的variables是在另一个控制器中创build的 ,但是只需要等到angular度评估它发送给应用程序控制器之后,我们可以使用$timeout
等待$apply
已经运行。 我们还需要使用$emit
将其发送到父范围应用程序控制器(由于指令中的隔离范围):
app.directive('yourDirective', ['$timeout', function ($timeout) { return { restrict: 'A', // NB: isolated scope!! scope: { yourDirective: '=' }, link: function (scope, element, attrs) { // wait until after $apply $timeout(function(){ console.log(scope.yourDirective); // use scope.$emit to pass it to controller scope.$emit('notification', scope.yourDirective); }); }, // the variable is available in directive controller, // and can be fetched as done in link function controller: [ '$scope', function ($scope) { // wait until after $apply $timeout(function(){ console.log($scope.yourDirective); // use $scope.$emit to pass it to controller $scope.$emit('notification', scope.yourDirective); }); }] }; }]) .controller('MyCtrl', ['$scope', function ($scope) { // variable passed to app controller $scope.$on('notification', function (evt, value) { console.log(value); $scope.variable = value; }); }]);
这里的HTML(没有括号!):
<div ng-controller="MyCtrl"> <div your-directive="someObject.someVariable"></div> <!-- use ng-bind in stead of {{ }}, when you can to avoids FOUC --> <div ng-bind="variable"></div> </div>
解决scheme#3
如果你的variables没有改变 ,你需要在你的指令中评估它,你可以使用$eval
函数:
app.directive('yourDirective', function () { return { restrict: 'A', // NB: no isolated scope!! link: function (scope, element, attrs) { // executes the expression on the current scope returning the result // and adds it to the scope scope.variable = scope.$eval(attrs.yourDirective); console.log(scope.variable); }, // the variable is available in directive controller, // and can be fetched as done in link function controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) { // executes the expression on the current scope returning the result // and adds it to the scope scope.variable = scope.$eval($attrs.yourDirective); console.log($scope.variable); } ] }; }) .controller('MyCtrl', ['$scope', function ($scope) { // variable passed to app controller $scope.$watch('variable', function (value) { if (value) { console.log(value); } }); }]);
这里的HTML(记住方括号!):
<div ng-controller="MyCtrl"> <div your-directive="{{ someObject.someVariable }}"></div> <!-- use ng-bind instead of {{ }}, when you can to avoids FOUC --> <div ng-bind="variable"></div> </div>
另外,看看这个答案: https : //stackoverflow.com/a/12372494/1008519
FOUC(无风格内容的闪光)的参考问题: http ://deansofer.com/posts/view/14/AngularJs-Tips-and-Tricks-UPDATED
感兴趣的是: 这里是关于angular度生命周期的文章