1

這裏的目標是有兩個不同的指令,技術上是兄弟姐妹共享功能。我會用其中一個,另一個裏面沒有一個角度控制器繼承範圍問題

但是,第二條指令將具有第一條的所有功能並添加一些小的添加。因此,我希望從「Parent」指令繼承到「Child」的功能。

我通過重新使用Child上的Parent的相同指令定義對象來實現此目的,但要更改的控制器/模板字段除外。

這一切都運行良好,直到我從我的ParentDirCtrl打到觀察者。由於某種原因,觀察者似乎設置正確,觀察mydir.obj1,但不知何故內部觀察者回調函數mydir.obj1變得未定義。

我假設一些關於_.extend/$controller正在改變如何$scope的工作所以mydir.obj1沒有在ParentDirCtrl定義,但我不知道爲什麼會是這樣。

Plunk

angular.module('plunker', []) 

// lodash 
.constant('_', _) 

.controller('MainCtrl', function($scope, $timeout) { 
    $scope.obj = { 
    name: 'John', 
    age: 30, 
    }; 
}) 


.controller('ParentDirCtrl', function($scope) { 
    var mydir = this; 

    mydir.doStuffInParent = function() { 
    alert('executed from the parent directive'); 
    } 

    $scope.$watch('mydir.obj1', function() { 
    // ==================================== 
    //    ERROR 
    // Why is 'mydir.obj1' undefined when 
    // occupation is set? 
    // ==================================== 
    mydir.obj1.occupation = 'Meteorologist'; 
    }); 
}) 


.directive('parentDirective', parentDirective) 


.directive('childDirective', function() { 
    // borrow the directive definition object from the parent directive 
    var parentDDO = parentDirective(); 

    // uodate the template and controller for our new directive 
    parentDDO.template = [ 
    '<div>', 
     '<p ng-click="mydir.doStuffInParent()">{{mydir.obj1.name}}</p>', 
     '<p ng-click="mydir.doStuffInChild()">{{mydir.obj1.age}}</p>', 
    '</div>' 
    ].join(''); 

    parentDDO.controller = function($scope, $controller, _) { 
     // extend 'this' with the Parent's controller 
     var mydir = _.extend(this, $controller('ParentDirCtrl', { $scope: $scope })); 

     mydir.doStuffInChild = function() { 
     alert("executed from the child directive"); 
     }; 
    }; 

    return parentDDO; 
}); 


// this will be moved to the top during declaration hoisting 
function parentDirective() { 
    return { 
    restrict:'E', 
    scope: {}, 
    bindToController: { 
     obj1: '=', 
    }, 
    template: '<div>{{mydir.obj1}}</div>', 
    controller: 'ParentDirCtrl', 
    controllerAs: 'mydir', 
    }; 
} 
+0

如果它們基本相同,爲什麼不能通過設置屬性來區分功能? – charlietfl

+0

孩子將會有一些功能覆蓋父母的功能,然後是父母不需要的功能。另外,它還會有一些觀察者來查看父項中不存在的屬性。這就是說,父母中的100%功能是兒童所需要的。需要很多條件來在單個指令中控制所有這些。 – diplosaurus

+0

'var mydir'是'this'用來自父控制器的屬性擴展的。我的理解是,這是從另一個控制器繼承的方式。 – diplosaurus

回答

1

obj1填充在兒童控制器實例 - 這就是爲什麼mydir.obj1父觀察者是不明確的。您可以通過直接範圍或通過傳遞到觀察者的參考訪問obj1

$scope.$watch('mydir.obj1', function(val) { 
    $scope.mydir.obj1.occupation = 'Meteorologist'; 
    // or 
    val.occupation = 'Meteorologis'; 
}); 

沒有繼承範圍在這裏 - 兩個控制器在同一範圍內運行。 Controller-AS語法讓你感到困惑 - 我會擺脫它來使事情更清晰。

+0

謝謝,我把你的建議和更新溝渠控制器 - 作爲語法。錯誤消失了,但現在觀察者根本沒有觸發:https://plnkr.co/edit/oVCoPW?p=preview看起來應該在觀察者應該觸發的'$ timeout'之後。 – diplosaurus

+1

要捕捉'angular.copy'所做的更改 - 將'$ watch'方法的第三個參數('objectEquality')設置爲'true'。 'angular.copy'不會更改目標的引用。 –

+0

啊,呵呵。應該一直使用$ watchCollection。謝謝! – diplosaurus