2016-10-17 84 views
2

我正在学习如何创建自定义角度指令,其中我想使用一些双向数据绑定;然而没有运气。角度指令 - 双向数据绑定问题

想法非常简单:我们有一个人员列表,当我选择其中的任何人时,我想在我的指示中显示所选人员的姓名(明细)。

之前,我贴了很多代码,这里是我的榜样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> 

不幸的是,数据绑定不工作,即使我可以看到项目已被选中。我在这里做错了什么?

编辑:
你的答案全部从我personDetail.html删除的NG-控制器,但是我想保持它(目前只包含一个微小的结合,但我想添加更多的功能,还有如按钮点击等)。

是否可以保持控制器?

回答

3

标记:<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' 
    } 
}; 

Demo

+0

'BindToController'做到了! –

3

您需要将选定的人员传递给指令。您已经在您的指令中暴露了“人员”变量,您需要将选定的人员传递给指令。而且你也不需要控制器的控制器。

更改指令的声明是这样的:

<person-detail person="vm.selectedPerson"></person-detail> 

编辑

另外在你的指令卸下控制器,没有必要额外的控制器。

<div> 
    <h3>Selected Name:</h3> 
    <h3>{{person.name}}</h3> 
</div> 

我已经创建了一个plunkr来演示解决方案。你可以看到它here

+0

除了'person = vm.selectedPerson',你还有其他的改变吗?我试图在我的本地解决方案中实现它,但它仍然无法正常工作......但Plunk(它是1-1副本)正在工作:) –

+0

是的,我已经移除了您正在使用的额外控制器指示。你可以检查我分享的plunkr。 –

+0

我编辑了我的答案来回答你的问题 –

2

您在directive中绑定的person应该是您未指定的元素中的属性。所以传递为:

<person-detail person="vm.selectedPerson"></person-detail> 

,并在指令模板中删除的ng-controller="personDetail as vm"提用它作为:

<div> 
    <h3>Selected Name:</h3> 
    <h3>{{person.name}}</h3> 
</div> 
3

你几乎没有。 我更新了plunkr
index.html中,你必须指定对象要绑定到,像这样:

<person-detail person="vm.selectedPerson"></person-detail> 

是不需要的personDetail.js文件。并在personDetail.html你必须取代vm.person.nameperson.name。 顺便说一句,因为角1.5,你可以使用angular-components这是更容易使用。