嵌套指令和原型继承

时间:2014-04-25 09:56:11

标签: angularjs

通常在使用隔离范围时,我使用中间vm对象传递我的模型对象,以避免原型继承问题。

说,我有一个指令指令A

 function directiveA() {
    return {
        restrict: 'E',
        scope: {
         myParam: '='
        },
    ...
   }
 }

我会在html中将其称为:

<directive-a  my-param="vm.someProperty"></directive-a>

但是现在我有一个嵌套属性的场景,我不知道如何通过我的模型而不会遇到原型继承问题:

function directiveB(){
 return {
     restrict: 'E',
     require: '^directiveA',
     scope: true
 }
}

因此,如果在directiveB中我为scope.myParam分配了一个新值,它将在directiveB的范围内创建一个新对象,而不是修改directiveA&#39的范围内的myParam属性。

如何避免此问题?

1 个答案:

答案 0 :(得分:0)

简短回答

要避免此问题,请将vm的整个对象传递给scope指令

<directive-a  my-param="vm"></directive-a>

<directive-b  my-param="vm"></directive-b>

注意:假设vm对象来自其父控制器。



LONG ANSWER

在您的回答中,当您通过vm.someProperty时,实际上将该属性的值传递给myParam,从而创建一个独立于其父级的新范围控制器。为了能够从父作用域修改属性,请传递vm对象的引用

如何通过Javascript传递值并通过引用传递? object.property = "newProperty"object = oldObject通过引用传递时传递值。 在这里,我创建了一个如何工作的例子,

<强> JS

// Pass By Value
var a = "helloProperty";
var b = a;
b = "modifiedProperty";
console.log(a); // prints helloProperty

// Pass By Value
var c = {};
c.someProperty = "helloProperty2";
var d = c.someProperty;
d = "modifiedProperty2";
console.log(c); // prints helloProperty2

// Pass By Reference
var e = {};
e.someProperty = "helloProperty3";
var f = {};
f = e;
f.someProperty = "modifiedProperty3";
console.log(e); // prints modifiedProperty3

CODE


回到原来的问题

正如在简短的回答中所说,设置隔离范围以通过引用传递将不会创建新范围,任何更改都将修改其父范围。

以下是问题的解决方案,

<强> HTML

<html ng-app="myApp">
<head>
  <meta charset="utf-8">
  <title>AngularJS: Nested Directives Accessing Scope Directives</title>
</head>
<body>
  <div class="main" ng-controller="appController">
    <directive-a my-param="vm">
        <directive-b my-param="vm"></directive-b>
    </directive-a>
  </div>
</body>
</html>

<强> JS

var app = angular.module('myApp',['myApp.controller', 'myApp.directive']);

angular.module('myApp.controller', []).controller('appController', ['$scope', function($scope){
    $scope.vm = {
        someProperty: ''
    };
    $scope.vm.someProperty = 'someVmProperty';
}]);

angular.module('myApp.directive', [])
    .directive('directiveA', function(){
        return {
            restrict: 'E',
            scope: {
                myParam: '='
            },
            controller: ['$scope', function($scope){
            }],
            link: function(scope, element, attrs){
                console.log(scope.myParam); // prints Object {someProperty: "modifiedProperty"}
            }
        }
    }).
    directive('directiveB', function(){
        return {
            restrict: 'E',
            require: '^directiveA',
            scope: {
                myParam: '='
            },
            controller: ['$scope',function($scope){
            }],
            link: function(scope, element, attrs){
                scope.myParam.someProperty = 'modifiedProperty';
            }
        }

    });

CODE

希望这会帮助你。干杯