#angularjs #data-binding #angular-directive
#angularjs #привязка данных #angular-директива
Вопрос:
Я изучаю создание пользовательских угловых директив, где я хотел бы использовать некоторую двустороннюю привязку данных; однако безуспешно.
Идея очень проста: у нас есть список людей, где, как только я выбираю любого из них, я хочу отобразить имя выбранного человека (подробно) в моей директиве.
Прежде чем я вставлю много кода, вот мой пример plunker:
https://plnkr.co/edit/xQJAWcYcscOaaNs8VlAI?p=preview
Вот что я сделал:
Создан главный контроллер:
(function() {
"use strict";
var controllerId = 'personController';
angular.module("app").controller(controllerId, ["$timeout", personController]);
function personController($timeout) {
var vm = this;
vm.name = "Janko";
vm.people = returnPeople();
vm.selectedPerson = {};
vm.selectPerson = function (person) {
//function to add a new Person
vm.selectedPerson = person;
console.log(vm.selectedPerson.name);
};
}
function returnPeople() {
return [
{
name: "Janko",
surname: "Hrasko",
age: 24,
gender: "M"
},
{
name: "Jozef",
surname: "Mrkvicka",
age: 26,
gender: "M"
},
{
name: "Janka",
surname: "Kratka",
age: 21,
gender: "F"
}
];
};
})();
Созданная директива:
(function () {
"use strict";
var app = angular.module("app");
app.directive('personDetail', personDetail);
function personDetail() {
return {
scope: {
person: "=person"
},
restrict: 'E',
templateUrl: '/js/person/templates/personDetail.html'
}
};
})();
** Создан контроллер сведений о персонале: **
(function() {
"use strict";
var controllerId = 'personDetail';
angular.module("app").controller(controllerId, ["$scope", personController]);
function personController($scope) {
var vm = this;
vm.person = $scope.person;
}
})();
Наконец — человек Detail.html
<div ng-controller="personDetail as vm">
<h3>Selected Name:</h3>
<h3>{{vm.person.name}}</h3>
</div>
К сожалению, привязка данных не работает, хотя я вижу, что элемент был выбран. Что я здесь делаю не так?
Редактировать:
Все ваши ответы удалили ng-controller из моего personDetail.html
, однако я хотел бы сохранить его (в настоящее время он содержит только одну незначительную привязку, но я хочу добавить туда больше функций, таких как нажатие кнопок и т. Д.).
Возможно ли сохранить контроллер?
Ответ №1:
разметка: <person-detail person="vm.selectedPerson"></person-detail>
function personDetailsController($scope) {
var vm = this;
//vm.person = $scope.person;// This will get executed only first time.
//Every time you assigning different object to it. Not changing object.property
}
Вы можете использовать контроллер в качестве синтаксиса следующим образом, который также сохраняет двустороннюю привязку.
function personDetail() {
return {
scope: {
person: "="
},
bindToController: true,
controller:'personDetailsController',
controllerAs: 'vm',
restrict: 'E',
templateUrl: 'personDetail.html'
}
};
Ответ №2:
Вам необходимо передать выбранного пользователя директиве. Вы предоставили переменную «person» в своей директиве, вам необходимо передать выбранное лицо директиве. А также вам не нужен контроллер для контроллера.
Измените объявление директивы следующим образом:
<person-detail person="vm.selectedPerson"></person-detail>
Отредактировано
Также удалите контроллер в вашей директиве, в этом дополнительном контроллере нет необходимости.
<div>
<h3>Selected Name:</h3>
<h3>{{person.name}}</h3>
</div>
Я создал plunkr для демонстрации решения. Вы можете увидеть это здесь.
Комментарии:
1. вы изменили что — нибудь еще , кроме
person=vm.selectedPerson
? Я пытался реализовать это в своем локальном решении, но оно по-прежнему не работает… тем не менее, Plunk (который является копией 1-1) работает 🙂2. Да, я удалил дополнительный контроллер, который вы используете в директиве. Вы можете проверить мой plunkr, которым я поделился.
3. @RobertJ. помогло ли это?
Ответ №3:
вы были почти там. Я обновил ваш plunkr
В index.html вы должны указать объект, к которому вы хотели бы привязаться, следующим образом:
<person-detail person="vm.selectedPerson"></person-detail>
В personDetail.js файл не нужен. И в personDetail.html вы должны заменить vm.person.name
на person.name
.
Кстати, начиная с angular 1.5, вы можете использовать угловые компоненты, которые несколько проще в использовании.
Ответ №4:
То person
, к чему вы привязываетесь, directive
должно содержать атрибут в элементе, который вы не указали. Так что передайте это как:
<person-detail person="vm.selectedPerson"></person-detail>
и в шаблоне директивы удалите упоминание об ng-controller="personDetail as vm"
использовании его как:
<div>
<h3>Selected Name:</h3>
<h3>{{person.name}}</h3>
</div>