角度绑定为对象
Angular bind as object
为澄清目的重新表述问题。
Plunkr
视图:
<input type="text" ng-model="form['data']['sampleData']">
<input type="text" ng-model="form[bindingPrefix][bindingSuffix]">
<input type="text" ng-model="form[bindingValue]">
控制器:
$scope.form = {
data: {
sampleData: '123'
}
};
$scope.bindingValue = 'data.sampleData';
$scope.bindingPrefix = 'data';
$scope.bindingSuffix = 'sampleData';
期望效果:我希望form[bindingValue]
能产生与form[bindingPrefix][bindingSuffix]
一样的效果,而无需特意将bindingValue
分离为bindingPrefix
和bindingSuffix
,因为bindingValue可以是数组中的动态值,如data.sampleData.childData
、data.sampleData.childData.childChildData
,用于ng重复模型。
p/S:bindingValue是从服务器端传来的东西,我无法控制它。
==========================================================================可能在这里的这个混蛋那里工作。理想情况下,不应修改视图。点击此处
即使路径可以是可变长度的,我们也可以将问题减少到只使用一个变量的路径。只要你不破坏数据对象的结构,这就应该有效(或者如果你破坏了,记得再次运行这个准备代码)。
所以我们有数据
$scope.form = {
data: {
sampleData: '123'//This could be even deeper in the object, can't know for sure
}
};
但我们需要保持CCD_ 8和包含对象之间链接的唯一变量名称是最后一个。"sampleData"。如果我们只获得对data
obejct和"sampleData"属性名称的引用,那么所有其他属性名称都可以被丢弃。
控制器内:
//Get the path from the server, split it to create an array of property names
var path = 'data.sampleData'.split('.');
//We'll start changing these soon
var prevValue = $scope.form, nextValue;
for(var i = 0; i < path.length - 1; i++){//Note that we are not looping all the way through (-1)!
//Get all the properties one by one
nextValue = prevValue[path[i]];
if(nextValue == undefined){
//This is an error, the data didn't conain the property that it was supposed to.
//It's up to you how to handle this. Doing the following will add the missing properties and keep things working.
nextValue = prevValue[path[i]] = {};
}
//The prevValue will first be $scope.form, then form.data
prevValue = nextValue;
}
//$scope.bindingContainer is a reference to $scope.form.data object
$scope.bindingContainer = prevValue;
//$scope.bindingValue is the last property name, "sampleData"
$scope.bindingValue = path[path.length-1];
在模板中:
<input type="text" ng-model="bindingContainer[bindingValue]">
一切都应该正常(再说一遍,只要你不改变$scope.form.data = somethingElse
)。
当然,我们有点作弊,因为现在模板根本没有引用原始的$scope.form
对象。不过,这并不重要,因为它引用了data对象及其属性"sampleData",所以只要$scope.form
引用了相同的data
对象,我们就可以获得所需的一切。
我创建了一个名为my-dynamic-model
的指令,它被<input>
元素引用。这包含对作用域变量$parsed
的引用,以引用正确的$scope.bindingValue
数组。
请参阅所附的工作plunkr。
现在,您可以将$scope.bindingValue
中的层次结构指定为所需的深度,它将正确更新$scope
变量。只需确保它是一个完整的$scope
对象层次结构路径。
代码:
var app = angular.module('app', []);
app.controller('MyController', function($scope) {
$scope.form = {
data: {
sampleData: '1234',
sampleData1: {
sampleData2: '2345'
}
}
};
$scope.bindingValue = ['form.data.sampleData', 'form.data.sampleData1.sampleData2'];
});
app.directive('myDynamicModel', function( $parse, $log ) {
return function( scope, el, attrs ) {
var model = $parse( attrs.myDynamicModel );
var finalModel = $parse(model(scope));
finalModel.assign(scope, finalModel(scope));
scope.$apply();
el.bind('keyup', function() {
finalModel.assign(scope, el.val());
if (!scope.$$phase) scope.$apply();
})
}
});
HTML:
<div ng-controller="MyController">
<input type="text" ng-model="form.data.sampleData" my-dynamic-model="bindingValue[0]" placeholder="Update me">
<input type="text" ng-model="form.data.sampleData1.sampleData2" my-dynamic-model="bindingValue[1]" placeholder="Update me too">
<div>{{ form.data.sampleData }}</div>
<div>{{ form.data.sampleData1.sampleData2 }}</div>
</div>
或者这可能与您当前使用angular、,这里还有一篇关于控制器语法的优秀文章。
function ExampleCtrl($scope) {
$scope.bindingValue = data.sampleData;
$scope.bindingPrefix = 'data';
$scope.bindingSuffix = 'sampleData';
}
// Controller or Controller as syntax is a reference the controller just a short-hand name.
<body ng-app="ExampleApp">
<div class="example" ng-controller="ExampleCtrl">
<input type="text" ng-model="bindingValue">
</div>
</body>
试试这样的东西,也许有一些语法差异:
function ExampleCtrl() {
var ctrl = this;
ctrl.bindingValue = data.sampleData;
ctrl.bindingPrefix = 'data';
ctrl.bindingSuffix = 'sampleData';
}
<body ng-app="ExampleApp">
<div class="example" ng-controller="ExampleCtrl as ctrl">
<input type="text" ng-model="ctrl.bindingValue">
</div>
</body>
在控制器中,创建一个范围对象,如下所示:
$scope.data = {
sampleData: {
childSampleData: null
},
anotherItem: null,
moreData: {
Child1: null,
Child2: null
}
}
您的HTML应该引用这样的范围对象:
<input type="text" ng-model="data.sampleData.childSampleData">
<input type="text" ng-model="data.anotherItem">
<input type="text" ng-model="data.moreData.Child1">
<input type="text" ng-model="data.moreData.Child1">
不幸的是,您不能像代码显示的那样引用ngModel
。所以说ng-model="form[bindingPrefix][bindingSuffix]"
是不正确的,因为您不能访问这里的form
对象。但是,您可以像我在HTML中那样使用点符号来访问子对象。
如果你不确定哪个ngModel
需要更新,你应该使用这样的函数:
<input type="text" ng-model="item1" ng-change="updateModel()">
$scope.updateModel = function() {
$scope.data[bindingPrefix][bindingSuffix] = $scope.item1;
}
- 值未与数组对象绑定
- Angular:将函数从子对象绑定到父对象
- 将 .on 事件与对象绑定
- 挖空选项对象绑定
- 对象绑定模式的rest属性应该是最后一个
- Knockout.js用单个json对象绑定一个可观察对象
- angular.js将jquery自动完成对象绑定到ng模型,将值输入到对象的属性
- Knockout:为许多数据对象绑定模板引导模式
- JavaScript 对象绑定
- 使用javascript将JSON对象绑定到asp.net gridview控件
- 如何将复杂对象绑定到剑道调度程序中的字段
- D3:如何有条件地将 SVG 对象绑定到数据
- Ko_selectize数组对象绑定未定义
- 在选择框中从任意 JavaScript 对象绑定选项值和选项文本
- 使用 jQuery 将对象绑定到一行
- 如何将当前对象绑定到文本输入
- AngularJS将javascript对象绑定到指令属性
- 子属性更改时重新评估对象绑定
- 将Angular Service对象绑定到控制器作用域并更新
- 将模型对象绑定到JavaScript数组时出现语法错误