我的目标是将projectName模型从我的MainController传递到我的自定义contenteditable指令。
我有以下控制器:
app.controller("MainController", function($scope){
$scope.projectName = "Hot Air Balloon";
});
以下是我如何调用该指令:
<div class="column" ng-controller="MainController">
<h2 contenteditable name="myWidget" ng-model="projectName" strip-br="true"></h2>
<p>{{projectName}}</p>
</div>
我已按照本教程获得了满足指令:https://docs.angularjs.org/api/ng/type/ngModel.NgModelController
如果我正确理解文档,那么Angular将不会使用我想要的模型。相反,它将创建一个新的模型w /本地范围的contenteditable指令。我知道我可以在指令中添加一个隔离范围,但我不知道如何使用传递给链接函数中隔离范围的模型。
我尝试过类似下面的东西但没有用......
<h2 contenteditable item="projectName"></h2>
---指令代码---
scope: {
item: '=item'
}
link: function(){
...
item.$setViewValue(...)
...
}
---我的原始指令调用 -
<div class="column" ng-controller="MainController">
<h2 contenteditable name="myWidget" ng-model="projectName" strip-br="true"></h2>
<p>{{projectName}}</p>
</div>
---我的原始控制器和指令---
app.controller("MainController", function($scope){
$scope.projectName = "LifeSeeds";
});
app.directive('contenteditable', function(){
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModel){
console.log(ngModel);
if(!ngModel) return;
console.log(ngModel.$viewValue);
ngModel.$render = function(){
element.html(ngModel.$viewValue || '');
};
element.on('blur keyup change', function(){
scope.$apply(read);
});
read();
function read(){
var html = element.html();
if(attrs.stripBr && html == '<br>'){
html = '';
}
ngModel.$setViewValue(html);
}
}
};
});
答案 0 :(得分:2)
您可以将ng-model与您自己的指令一起使用。要确保包含该属性,您可以使用以下属性require
:
app.directive("myDirective", function(){
return {
require:"ngModel",
link: function(scope, element, attr, ngModel){
console.log(ngModel);
}
}
});
然后,您可以在指令中编写您想要的ng-model行为。
答案 1 :(得分:1)
工作解决方案:http://plnkr.co/edit/Lu1ZG9Lpx2sl8CYe8FCx?p=preview
我提到我在原帖中尝试使用隔离范围。
<h2 contenteditable item="projectName"></h2>
这实际上是正确的方法,所以使用指令链接函数的模型参数忽略我的完整原始示例。
link: function(scope, element, attrs, ngModel)
隔离范围方法不起作用的原因是$ scope.projectName存储了一个原语而不是一个对象。我不懂一些javascript基础知识。主要是,我不知道原始类型是按值传递给函数的。
基元在javascript中按值传递。因此,对函数中的原始值所做的更改不会更改传递给函数的变量的值。
function changeX(x){
x = 5;
}
x = 4;
changeX(x);
console.log(x) // will log 4 ... Not 5
但是,传递给javascript函数的对象是通过引用传递的,因此函数中对它们的修改将被传递给传递给函数的变量。
我的问题在于如何在MainController中声明范围。
我有:
$scope.projectName = "LifeSeeds";
这是一个原始的。当我将projectName传递给指令时,我传递了一个原语。
<h2 contenteditable item="projectName"></h2>
因此,对可编辑元素的更改是针对指令中的值而不是针对存储在MainController范围中的值。解决方案是将值存储在MainController范围内的对象中。
// correct
$scope.project = {
html: "Editable Content"
};
// wrong
$scope.projectName = "Editable Content"