AngularJS - привязать ng-модель к переменной, имя которой хранится внутри другой переменной
Я пытаюсь связать значение поля ввода с переменной.
Я не знаю имя этой переменной априори; он сохраняется в другой переменной.
Это html:
<body ng-controller="stageController">
<form name="myForm" novalidate="">
<input type="text" name="myText" ng-model="model" />
</form>
</body>
и это контроллер:
function stageController($scope) {
$scope.model = 'realModel'; // contains the name of the variable that i would bind to the field
$scope.realModel = 'initial value of the field';
}
Я сделал также fiddle.
Это не работает, поскольку в настоящее время привязка находится между полем ввода и переменной model
. Вместо этого я бы привязал поле ввода к переменной, имя которой хранится внутри переменной $scope.model
(в данном случае realModel
).
Возможно ли это? Как?
Ответы
Ответ 1
Да, возможно. Я не понимаю, почему вы хотите это сделать, но я могу показать вам, как это сделать. Я не мог начать скрипку, но я скопировал ее в plnkr: http://plnkr.co/edit/o1gFf1lMq4Pg5iVoVyUN?p=preview
Вы создаете директиву, которая преобразует исходный шаблон в новый с помощью компиляции. Новая директива:
directive('ngBindModel',function($compile){
return{
compile:function(tEl,tAtr){
tEl[0].removeAttribute('ng-bind-model')
return function(scope){
tEl[0].setAttribute('ng-model',scope.$eval(tAtr.ngBindModel))
$compile(tEl[0])(scope)
console.info('new compiled element:',tEl[0])
}
}
}
})
Обновлен html (изменение с ng-model на ng-bind-model, новая директива)
<input type="text" name="myText" ng-bind-model="model" />
Ответ 2
Простейшая альтернатива - при условии, что можно немного изменить модель - HTML:
<body ng-controller="stageController">
<form name="myForm" novalidate="">
<input type="text" name="myText" ng-model="vars[model]" />
</form>
</body>
Модель:
function stageController($scope) {
$scope.model = 'realModel'; // contains the name of the variable that i would bind to the field
$scope.vars = {}; // variables container
$scope.vars.realModel = 'initial value of the field';
}
Ответ 3
Я попытался использовать предыдущий ответ внутри ng-repeat
, и это не сработало. Он использует функцию compile
, что означает, что все директивы использовали последний переданный в значении. Если вы используете функцию ссылки, она работает как ожидалось, т.е.
.directive('ngBindModel',function($compile){
return{
link:function(scope,element,attr){
element[0].removeAttribute('ng-bind-model');
element[0].setAttribute('ng-model',scope.$eval(attr.ngBindModel));
$compile(element[0])(scope);
}
};
})
Ответ 4
Ответ (в настоящее время выигранный) пользователем2273266 на самом деле тонко неверен. Хотя он будет работать, если вы используете только одну директиву один раз, он фактически путает элементы элемента шаблона и экземпляра объекта и будет помещать фамилию, которую он находит на ВСЕХ элементах, которые он отображает в цикле, например.
directive('custBindModel',function($compile){
return{
compile:function(tEl){
tEl[0].removeAttribute('cust-bind-model');
return function(scope, iEl, iAtr){
iEl[0].setAttribute('ng-model',scope.$eval(iAtr.custBindModel));
$compile(iEl[0])(scope);
console.info('new compiled element:',tEl[0]);
}
}
}
})
Эта версия исправляет проблему, разделяя операции над шаблоном и экземпляром, поэтому вызов после ссылки изменяет только экземпляр, а не шаблон.
Также изменился префикс 'ng', который зарезервирован.
Ответ 5
Я относительно новичок в Angularjs. Я знаю, что вы запрашиваете в Javascript, используя окно. Я не уверен в Angular. Я изменил код для достижения практически возможного решения:
$scope.model = {'var':'realModel','value':'initial value of the field'};
Попробуйте fiddle:
Ответ 6
Что вам здесь не хватает, это директива ng-app, нет необходимости использовать явные директивы для ng-модели.
Это работает:
<body ng-app="myApp" ng-controller="stageController">
<form name="myForm" novalidate="">
<input type="text" name="myText" ng-model="realModel" />
</form>
<script>
var app = angular.module('myApp', []);
app.controller('stageController', function($scope) {
$scope.model = 'realModel';
$scope.realModel = 'initial value of the field';
})
</script>
</body>