AngularJS,带有 getter 和 setter 的单选按钮
AngularJS, radio buttons with getters and setters
我试图让单选按钮通过 getter 和 setters 控制外部对象的布尔属性。
下例中有多个Person
,但只能有一个happy
。其中一个已经很高兴了。我想通过单选按钮控制哪个开心。
因此,我创建了一个带有无线电输入的模板,但我无法将它绑定到 person.happy
,因为我无权访问此 属性(假设 Person
是第三方库)。
为了将某些内容绑定到输入,我创建了一个哑控制器,以提供默认值(Person
值),并将更改传播到实际变量(简而言之,调用 setter).我似乎无法把事情做好。
var app = angular.module('app', []);
// Person constructor ; happy is a private member
function Person(name, isHappy) {
var happy = isHappy;
this.name = name;
this.getHappy = function() { return happy; }
this.setHappy = function(value) { happy = value; }
}
// Inject a person list in the scope
app.controller('PeopleCtrl', function($scope) {
$scope.people = [
new Person('Alice', true),
new Person('Bob', false),
new Person('Carol', false)
];
});
// Template to display one person + happiness controller
var humanTemplate = [
'<div><label>',
'<input type="radio" name="group" ng-model="me.happy" ng-change="me.toggle()" value="{{ !me.happy }}">',
'<span>{{ person.name }} is {{ me.happy ? "happy" : "sad" }}</span>',
'</label></div>'
].join('');
// Directive to display one person
app.directive('human', function() {
return {
restrict: 'E',
template: humanTemplate,
scope: {
person: '='
},
controllerAs: 'me',
controller: function($scope) {
var me = this;
me.happy = $scope.person.getHappy();
me.toggle = function() {
console.log(me.happy);
$scope.person.setHappy(me.happy);
};
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
<div ng-app="app" ng-controller="PeopleCtrl">
<human ng-repeat="p in people" person="p"></human>
</div>
我原以为 ngChange
会与单选框和复选框上的 checked
状态相关联(这在某种程度上是合乎逻辑的),但有一些症状告诉我并非如此:
ngChange
未针对先前检查的无线电 触发
ngChange
不会触发超过一次(我在弄乱输入 value
属性时触发了两次)
我是新手,可能记错了,不过看来ngChange
不是我想要的
您认为什么是解决此问题的好方法?
我是否需要编写一个父控制器来手动管理某些项目在其他项目被激活时的停用?
我认为(至少我从演示中看到的)您使用单选按钮的目的不同。
单选按钮在每个按钮共享 ng-model
的组中工作。在你的例子中,human
指令有自己的作用域,因此每个单选按钮都有自己的模型 a.e。独立的,打破了单选按钮的概念和用法。
更改为经典复选框type="checkbox"
,一切都会正常工作
我试图让单选按钮通过 getter 和 setters 控制外部对象的布尔属性。
下例中有多个Person
,但只能有一个happy
。其中一个已经很高兴了。我想通过单选按钮控制哪个开心。
因此,我创建了一个带有无线电输入的模板,但我无法将它绑定到 person.happy
,因为我无权访问此 属性(假设 Person
是第三方库)。
为了将某些内容绑定到输入,我创建了一个哑控制器,以提供默认值(Person
值),并将更改传播到实际变量(简而言之,调用 setter).我似乎无法把事情做好。
var app = angular.module('app', []);
// Person constructor ; happy is a private member
function Person(name, isHappy) {
var happy = isHappy;
this.name = name;
this.getHappy = function() { return happy; }
this.setHappy = function(value) { happy = value; }
}
// Inject a person list in the scope
app.controller('PeopleCtrl', function($scope) {
$scope.people = [
new Person('Alice', true),
new Person('Bob', false),
new Person('Carol', false)
];
});
// Template to display one person + happiness controller
var humanTemplate = [
'<div><label>',
'<input type="radio" name="group" ng-model="me.happy" ng-change="me.toggle()" value="{{ !me.happy }}">',
'<span>{{ person.name }} is {{ me.happy ? "happy" : "sad" }}</span>',
'</label></div>'
].join('');
// Directive to display one person
app.directive('human', function() {
return {
restrict: 'E',
template: humanTemplate,
scope: {
person: '='
},
controllerAs: 'me',
controller: function($scope) {
var me = this;
me.happy = $scope.person.getHappy();
me.toggle = function() {
console.log(me.happy);
$scope.person.setHappy(me.happy);
};
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
<div ng-app="app" ng-controller="PeopleCtrl">
<human ng-repeat="p in people" person="p"></human>
</div>
我原以为 ngChange
会与单选框和复选框上的 checked
状态相关联(这在某种程度上是合乎逻辑的),但有一些症状告诉我并非如此:
ngChange
未针对先前检查的无线电 触发
ngChange
不会触发超过一次(我在弄乱输入value
属性时触发了两次)
我是新手,可能记错了,不过看来ngChange
不是我想要的
您认为什么是解决此问题的好方法? 我是否需要编写一个父控制器来手动管理某些项目在其他项目被激活时的停用?
我认为(至少我从演示中看到的)您使用单选按钮的目的不同。
单选按钮在每个按钮共享 ng-model
的组中工作。在你的例子中,human
指令有自己的作用域,因此每个单选按钮都有自己的模型 a.e。独立的,打破了单选按钮的概念和用法。
更改为经典复选框type="checkbox"
,一切都会正常工作