Angular 控制器继承范围问题
Angular controller inheritance scoping issues
这里的目标是让两个不同的指令在技术上是兄弟姐妹共享功能。我会使用一个 或 另一个,永远不会 inside 另一个。
但是,第二个指令将具有第一个指令的所有功能,并进行一些小的添加。因此,我希望 继承 从 "Parent" 指令到 "Child".
的功能
我通过在子对象上重复使用来自父对象的相同指令定义对象来实现这一点,但 controller/template 字段已更改。
在我从我的 ParentDirCtrl
中击中观察者之前,这一切都运行良好。出于某种原因,观察者似乎已正确设置为观察 mydir.obj1
,但观察者回调函数 mydir.obj1
内部不知何故变得未定义。
我假设 _.extend
/$controller
正在改变 $scope
的工作方式,因此 mydir.obj1
未在 ParentDirCtrl
中定义, 但我不确定为什么会这样。
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',
};
}
obj1
填充在子控制器实例上 - 这就是为什么 mydir.obj1
在父观察器中未定义的原因。您可以直接通过作用域访问 obj1
或使用传递给观察者的引用:
$scope.$watch('mydir.obj1', function(val) {
$scope.mydir.obj1.occupation = 'Meteorologist';
// or
val.occupation = 'Meteorologis';
});
这里没有作用域继承——两个控制器在同一个作用域上运行。 Controller-AS 语法让您感到困惑 - 我会去掉它以使事情更清楚。
这里的目标是让两个不同的指令在技术上是兄弟姐妹共享功能。我会使用一个 或 另一个,永远不会 inside 另一个。
但是,第二个指令将具有第一个指令的所有功能,并进行一些小的添加。因此,我希望 继承 从 "Parent" 指令到 "Child".
的功能我通过在子对象上重复使用来自父对象的相同指令定义对象来实现这一点,但 controller/template 字段已更改。
在我从我的 ParentDirCtrl
中击中观察者之前,这一切都运行良好。出于某种原因,观察者似乎已正确设置为观察 mydir.obj1
,但观察者回调函数 mydir.obj1
内部不知何故变得未定义。
我假设 _.extend
/$controller
正在改变 $scope
的工作方式,因此 mydir.obj1
未在 ParentDirCtrl
中定义, 但我不确定为什么会这样。
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',
};
}
obj1
填充在子控制器实例上 - 这就是为什么 mydir.obj1
在父观察器中未定义的原因。您可以直接通过作用域访问 obj1
或使用传递给观察者的引用:
$scope.$watch('mydir.obj1', function(val) {
$scope.mydir.obj1.occupation = 'Meteorologist';
// or
val.occupation = 'Meteorologis';
});
这里没有作用域继承——两个控制器在同一个作用域上运行。 Controller-AS 语法让您感到困惑 - 我会去掉它以使事情更清楚。