为了澄清目的而重述问题。
Plunkr
查看:
AppDelegate
控制器:
<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
,因为bindingValue可能是动态值,例如{{1}数组中的{},bindingSuffix
用于ng-repeat模型。
P / S:bindingValue从服务器端传递,我无法控制它。
=============================================== =========================== 可以在这里使用这个plunkr工作。理想情况下,不应修改视图。Click here
答案 0 :(得分:1)
我创建了一个名为my-dynamic-model
的指令,该指令由<input>
元素引用。这包含对范围变量的引用,$parsed
引用正确的$scope.bindingValue
数组。
请参阅附件 plunkr 。
现在,您可以将$scope.bindingValue
中的层次结构指定为您想要的深度,并且它将正确更新该$scope
变量。只需确保它是一个完整的$scope
对象层次结构路径。
<强> CODE:强>
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>
答案 1 :(得分:1)
即使路径可以是可变长度,我们也可以将问题简化为仅使用一个变量的路径。只要您不打破数据对象的结构(或者如果您这样做,请记住再次运行此准备代码),这应该有效。
所以我们有数据
$scope.form = {
data: {
sampleData: '123'//This could be even deeper in the object, can't know for sure
}
};
但是我们需要保持sampleData
和包含对象之间链接的唯一变量名称是最后一个。 &#34;的sampleData&#34 ;.如果我们只是引用data
obejct和&#34; sampleData&#34;那么所有其他属性名称都可以丢弃。财产名称。
在控制器中:
//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 对象及其属性&#34; sampleData&#34;,所以只要$scope.form
引用了相同 data
对象我们已经得到了所有我们需要的东西。
答案 2 :(得分:0)
或者这可能与你目前使用angular写的一行有关, 这里也是一个优秀的article控制器作为语法。
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>
答案 3 :(得分:0)
在您的控制器中,创建一个这样的范围对象:
$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;
}