Как установить angular значение свойства объекта контроллера из директивы в области содержимого
У меня есть директива внутри ng-повторителя, которая должна установить свойство scope.
Смотрите здесь скрипку: http://jsfiddle.net/paos/CSbRB/
Проблема заключается в том, что свойство scope задано как значение атрибута, подобное этому:
<button ng-update1="inputdata.title">click me</button>
Директива должна установить свойство scope inputdata.title для некоторой строки. Это не работает:
app.directive('ngUpdate1', function() {
return function(scope, element, attrs) {
element.bind('click', function() {
scope.$apply(function() {
scope[ attrs.ngUpdate1 ] = "Button 1";
});
});
};
});
Однако назначение напрямую работает:
scope["inputdata"]["title"] = "Button 1";
Не могли бы вы рассказать мне, как я могу установить свойство scope. обозначение в его имени из директивы?
PS: Причина, по которой скрипта использует ретранслятор, заключается в том, что он делает директивы в области дочерних объектов. Когда они находятся в дочерней области, вы не можете писать свойства области, которые являются примитивами. Вот почему мне нужно свойство объекта с. во имя. Посмотрите длинное объяснение здесь: Каковы нюансы объема прототипа/прототипного наследования в AngularJS?
Спасибо
Ответы
Ответ 1
$parse решит вашу проблему.
<button ng-update1="inputdata.title">
app.directive('ngUpdate1', function($parse) {
return function(scope, element, attrs) {
var model = $parse(attrs.ngUpdate1);
console.log(model(scope)); // logs "test"
element.bind('click', function() {
model.assign(scope, "Button 1");
scope.$apply();
});
};
});
Fiddle
Всякий раз, когда директива не использует область выделения и вы указываете свойство scope с использованием атрибута, и вы хотите изменить значение, используйте $parse
.
Если вам не нужно изменять значение, вы можете вместо этого использовать $eval
:
console.log(scope.$eval(attrs.ngUpdate1));
Ответ 2
Не знаю, какова общая цель, но один способ - создать 2 атрибута, один для целевого объекта, а другой для свойства этого объекта:
<button ng-update1 obj="inputdata" prop="title">
app.directive('ngUpdate1', function() {
return function(scope, element, attrs) {
element.bind('click', function() {
scope.$apply(function() {
scope[ attrs.obj ][attrs.prop] = "Button 1";
});
});
};
});
DEMO: http://jsfiddle.net/CSbRB/9/
Альтернативно, используя существующий формат, вы могли бы split()
значение вашего текущего атрибута ng-update1
и использовать массив результатов для объекта и свойства в нотации
element.bind('click', function() {
var target=attrs.ngUpdate1.split('.');
scope.$apply(function() {
scope[ target[0] ][target[1]] = "Button 1";
});
});
DEMO с обоими подходами: http://jsfiddle.net/CSbRB/10/
Еще один подход, при котором вы создаете изолированную область действия в директиве и можете передать ссылку на объект inputdata
и вывести имя свойства из атрибута (такая же разметка как вторая версия):
app.directive('ngUpdate3', function () {
return {
scope: {
targetObject: '=obj'
},
link: function (scope, element, attrs) {
element.bind('click', function () {
scope.$apply(function () {
scope.targetObject[attrs.prop]='Button 3';
});
});
}
}
});
http://jsfiddle.net/CSbRB/11/