无法从控制器通过/更新ngModel到指令 [英] Unable to pass/update ngModel from controller to directive
问题描述
我使用的UI插件的选择,我路过纳克模型从我的控制器称为richSelect自定义指令,但NG-模型不似乎得到更新选择任何项目。
< richselect NG模型=数据模型>< / richselect>
自定义指令
app.directive('richselect',['$编译,函数($编译){
返回{
限制:AE,
范围: {
ngModel:'='/ *与对象相关联*型号/
},
链接:功能(范围,元素,ATTRS,ngModel){
scope.options = [
{
值:VALUE1,
说明:值一号
},
{
'值':'值',
说明:值的两个
}
]
scope.getRichSelectTemplate =功能(){ 回归'< UI选多个NG模型=ngModel主题=引导NG-禁用=禁用>' +
{{ngModel}}< UI的选择匹配占位=选择> {{$ select.selected.Desc}}< / UI选匹配>' +
'< UI的选择,选择重复=,在选项选项|过滤器:$ select.search>' +
'<跨度NG绑定-HTML =option.Desc |亮点:$ select.search>< / SPAN>' +
'< / UI的选择,选择>' +
'< / UI选>';
} VAR linkFn = $编译(scope.getRichSelectTemplate())(范围);
element.append(linkFn);
}
}
}]);
Plnkr: http://plnkr.co/edit/Im8gpxEwnU7sgrKgqZXY?p=preVIEW
下面,试试这个。我不完全相信你试图得到什么格式或输出,但是这得到所选的选项传递给视图。
- 修改 - 我摆脱了曾经是这里的plunker的
您必须使用 ngModel。$ setViewValue
,以改变在视图中的指令NG-模式的价值。此外,获得的价值UI的选择,你需要有NG-模型指着 options.selected
然后,它只是一个增加一个 NG-点击
这指出了更新的观点与 ngModel功能的问题。$ setViewValue(范围.options.selected
。
另外,我相信你需要`要求:ngModel在你的指令,以便您可以访问ngModelController
app.directive('richselect',['$编译,函数($编译){
返回{
限制:AE,
要求:'ngModel',
范围: {
胡说:'='/ *与对象相关联*型号/
},
链接:功能(范围,元素,ATTRS,ngModel){
scope.changer =功能(){
ngModel。$ setViewValue(scope.options.selected)
的console.log(scope.options.selected)
}
scope.options = [
{
值:VALUE1,
说明:值一号
},
{
'值':'值',
说明:值的两个
}
]
scope.getRichSelectTemplate =功能(){ 回归'< UI选多个NG模型=options.selected主题=引导NG点击=换碟机()NG-禁用=禁用>' +
{{options.selected}}< UI的选择匹配占位=选择> {{$ select.selected.Desc}}< / UI选匹配>' +
'< UI的选择,选择重复=,在选项选项|过滤器:$ select.search>' +
'<跨度NG绑定-HTML =option.Desc |亮点:$ select.search>< / SPAN>' +
'< / UI的选择,选择>' +
'< / UI选>';
} VAR linkFn = $编译(scope.getRichSelectTemplate())(范围);
element.append(linkFn);
}
}
}]);
编辑:
很多挖掘和修补,每下面的评论后 - 让双向绑定工作已证明有些难以捉摸。我发现这是很容易使用标准的用户界面,选择指令做,因为在这里看到(例如修改code从UI选择),因为我们可以很容易地访问指令的适用范围:
标准指令演示
我也碰到了类似的包装作为一个在OP,但与它玩耍后,那人似乎有同样的问题 - 它很容易得到的东西,但是如果你需要将数据推入指令它不想去。
有趣的是,在我上面的解决方案,我可以看到`scope.options.selected'对象实际上包含的数据,只是从来没有下来的UI选指令的范围,因此从来没有允许我们在推送数据。
遇到了类似的问题在一个项目中我的工作在不同的包装指令后,我想通了,如何通过不同的范围将数据推了下来。
我的解决办法是修改UI选脚本本身,并称一个变量在它的 $父
检查范围内$监控功能。由于UI的选择指令使用范围:真正的
,它会创建一个子作用域(其中,如果我没有记错的话,家长会在这个OP指令)<。 / p>
唐氏在uiSelect指令的链接功能的底部添加以下的手表功能:
范围。$表(函数(){
返回范围$ parent.myVar。
},功能(的newval){
$ select.selected =的newval;
})
在这里我们directve的链接功能,我添加了这个$腕表功能:
范围。$表(函数(){
返回ngModel $ viewValue。
},功能(的newval){
scope.myVar =的newval;
})
所以,这里所发生的是,如果$ viewValue变化(即我们从一个HTTP服务,等来了数据模型
绑定,$手表功能分配一些数据会抓住它,并把它分配给scope.myVar,与UI选择脚本中的$手表功能的手表范围。$ parent.myVar更改(我们告诉它看在它的父范围的变量)。如果它看到这促使他们任何修改 $ select.selected
- 这是用户界面,选择保留已选定的任何值,通过单击某个项目下拉列表。我们只是重写,并插入我们想要的任何值。
I'm using ui-select plugin and I'm passing ng-model from my controller to a custom directive called richSelect but the ng-model doesn't seemed to get updated on select of any item.
<richselect ng-model="dataModel"></richselect>
Custom directive
app.directive('richselect', ['$compile', function ($compile) {
return {
restrict: 'AE',
scope: {
ngModel: '=' /* Model associated with the object */
},
link: function (scope, element, attrs, ngModel) {
scope.options = [
{
'Value' : 'value1',
'Desc' : 'Value One'
},
{
'Value' : 'value2',
'Desc' : 'Value Two'
}
]
scope.getRichSelectTemplate = function () {
return '<ui-select multiple ng-model="ngModel" theme="bootstrap" ng-disabled="disabled">' +
'{{ngModel}} <ui-select-match placeholder="Select">{{$select.selected.Desc}}</ui-select-match>' +
'<ui-select-choices repeat="option in options | filter: $select.search">' +
'<span ng-bind-html="option.Desc | highlight: $select.search"></span>' +
'</ui-select-choices>' +
'</ui-select>';
}
var linkFn = $compile(scope.getRichSelectTemplate())(scope);
element.append(linkFn);
}
}
}]);
Plnkr : http://plnkr.co/edit/Im8gpxEwnU7sgrKgqZXY?p=preview
Here, try this. I wasn't exactly sure what format or output you were trying to get, but this gets the selected options passed to the View.
- EDIT - I got rid of the plunker that used to be here.
You have to use the ngModel.$setViewValue
in order to change the value of ng-model in the directive in the view. Additionally, to get the value of the ui-select, you need to have ng-model pointed at the options.selected
Then it was just a matter of adding an ng-click
that pointed to a function that updated the view with ngModel.$setViewValue(scope.options.selected
.
Also, I believe you need to `require: 'ngModel' in your directive so you can access the ngModelController.
app.directive('richselect', ['$compile', function ($compile) {
return {
restrict: 'AE',
require: 'ngModel',
scope: {
blah: '=' /* Model associated with the object */
},
link: function (scope, element, attrs, ngModel) {
scope.changer = function() {
ngModel.$setViewValue(scope.options.selected)
console.log(scope.options.selected)
}
scope.options = [
{
'Value' : 'value1',
'Desc' : 'Value One'
},
{
'Value' : 'value2',
'Desc' : 'Value Two'
}
]
scope.getRichSelectTemplate = function () {
return '<ui-select multiple ng-model="options.selected" theme="bootstrap" ng-click="changer()" ng-disabled="disabled">' +
'{{options.selected}} <ui-select-match placeholder="Select">{{$select.selected.Desc}}</ui-select-match>' +
'<ui-select-choices repeat="option in options | filter: $select.search">' +
'<span ng-bind-html="option.Desc | highlight: $select.search"></span>' +
'</ui-select-choices>' +
'</ui-select>';
}
var linkFn = $compile(scope.getRichSelectTemplate())(scope);
element.append(linkFn);
}
}
}]);
EDIT: After a lot of digging and tinkering, per the comment below - getting two-way binding working has proved somewhat elusive. I found it was quite easy to do using the standard ui-select directive, as seen here (modified example code from ui-select), because we can easily get access to the scope of the directive: Standard Directive Demo
I also came across a similar wrapper as the one in the OP, but after playing with it,that one seemed to have the same issue - it's easy to get stuff out, but if you need to push data into the directive it doesn't want to go. Interestingly, in my solution above, I can see that the `scope.options.selected' object actually contains the data, it just never gets down the the scope of the ui-select directive, and thus never allows us to push data in.
After encountering a similar issue with a different wrapper directive in a project I am working on, I figured out how to push data down through the different scopes.
My solution was to modify the ui-select script itself, adding an internal $watch function that checked for a variable in it's $parent
scope. Since the ui-select directive uses scope: true
, it creates a child scope (which, if I am not mistaken, the parent would be the directive in this OP).
Down at the bottom of the link function of the uiSelect directive I added the following watch function:
scope.$watch(function() {
return scope.$parent.myVar;
}, function(newVal) {
$select.selected = newVal;
})
In the link function of our directve here, I added this $watch function:
scope.$watch(function() {
return ngModel.$viewValue;
}, function(newVal) {
scope.myVar = newVal;
})
So what happens here is that if the $viewValue changes (i.e., we assign some data from a http service, etc. to the dataModel
binding, the $watch function will catch it and assign it to scope.myVar. The $watch function inside the ui-select script watches scope.$parent.myVar for changes (We are telling it to watch a variable on the scope of it's parent). If it sees any changes it pushes them to $select.selected
- THIS is where ui-select keeps whatever values that have been selected by clicking an item in the dropdown. We simply override that and insert whatever values we want.
这篇关于无法从控制器通过/更新ngModel到指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!