2015-10-15 1 views
8

Давать код внутри моего контроллера:Использование выражений в ngModel в Angular.js

$scope.entity = { 
    firstName: 'Jack', 
    lastName: 'Bauer', 
    location: { 
    city: 'New York' 
    } 
}; 
$scope.path = 'location.city'; 

Как динамически связываются ngModel к свойству entity указанного path?

Я пытался что-то вроде этого, но безрезультатно:

<input ng-model="'entity.' + path"> 

ответ

7

Слава, я не слишком уверен, что это хорошая идея для начала. Но так или иначе, Вам нужно сделать вашу модель getterSetter осведомленной, добавив это свойство на ваш вход ng-model-options="{ getterSetter: true }. Тогда вам нужна функция в вашем контроллере, которая строит getterSetter из укуса.

<input type="text" ng-model="propertify('entity.' + path)" ng-model-options="{ getterSetter: true }"> 

Вот как выглядел бы получившийся шаблон.

К счастью, у углового есть служба разбора $, которая делает это намного проще. поэтому что-то вроде этого должно быть в вашем контроллере или даже лучше в инжектируемой службе.

$scope.propertify = function (string) { 
     var p = $parse(string); 
     var s = p.assign; 
     return function(newVal) { 
      if (newVal) { 
       s($scope,newVal); 
      } 
      return p($scope); 
     } ; 
    }; 

Это будет возвращать функцию улавливающего устройства, которая обрабатывает это для вас. См. Его в действии в this plunk

+0

Sander, вы - Angular-ninja для реального, спасибо вам большое! =) –

+0

Я все еще получаю ошибку «не назначаемый» с этим ... но ваш plunkr работает нормально – ProblemsOfSumit

+0

У меня была неправильная угловая версия - все отлично работает, спасибо! – ProblemsOfSumit

2

Вы можете использовать кронштейн обозначения с небольшой модификацией, как вы хотите связать с вложенной собственности. Вы должны разделить путь к собственности:

<input ng-model="entity[locationKey][cityKey]"/> 

Контроллер:

$scope.locationKey = 'location'; 
$scope.cityKey = 'city'; 

См js fiddle

+0

Спасибо, но это не будет делать, я сохраняю полный путь в одной переменной, то есть суть проблемы. –

7

Update

Это не работает, как ожидалось, значение отображается правильно, но не может быть изменено. Правильное решение предоставляется Sander here.


Неправильное решение

Вау, решил его случайно:

<input type="text" ng-model="$eval('entity.' + path)"> 

И вот Plunk.

Надеюсь, это поможет кому-то.

1

После прочтения и использования ответа Сандера Элиаса я использовал это, но столкнулся с другой проблемой.

При объединении его результат с ng-required="true" в <input> вы не могли очистить поле, потому что, когда поле будет пустым, newVal передается как undefined.

После нескольких исследований я нашел an isssue on GitHub, который адресовал и решает эту проблему.

Вот что Сандера и GitHub ответ в сочетании выглядят как:

$scope.propertify = function (string) { 
    var property = $parse(string); 
    var propAssign = property.assign; 
    return function (newVal) { 
     if (arguments.length) { 
      newVal = angular.isDefined(newVal)? newVal : ''; 
      propAssign($scope, newVal); 
     } 
     return property($scope); 
    }; 
}; 

argument.length отражает количество значений, которые передаются в геттер/сеттер и будет 0 на Досталось и 1 на множестве ,

Besided, что я добавил angular.isDefined() в Sumit suggested in a comment также сохранить false и пустые ("") значения.

Вот updated Plunker