gpt4 book ai didi

javascript - Angularjs - ngModel.$setViewValue 不是函数

转载 作者:行者123 更新时间:2023-11-29 10:15:57 25 4
gpt4 key购买 nike

这是我的 plunker,我无法开始工作的代码从第 32 行开始 http://plnkr.co/edit/pmCjQL39BWWowIAgj9hP?p=preview

我正在尝试将与 Markdown 过滤器等效的应用到指令上...我创建了过滤器并通过手动应用过滤器进行了测试并且它以这种方式工作,但我应该只在内容类型时有条件地使用过滤器on 指令设置为 Markdown 。

我试图通过更新 ng-model 来完成此操作 >>> ngModel.$setViewValue(html) 但我收到错误ngModel.$setViewValue 不是一个函数。这让我觉得尽管指令要求 Controller 无法识别。

这是一个工作 Controller :

var app = angular.module('testOne', ["ngResource", "ngSanitize"]);

app.controller('testOneCtrl', function ($scope) {

$scope.product = {
id:12,
name:'Cotton T-Shirt, 2000',
description:'### markdown\n - list item 1\n - list item 2',
price:29.99
};

});

app.directive("myText", function ($parse) {
return {
restrict: "E",
require: "?ngModel",
scope:{
css: "@class", type: "@type"
},
controller: function ($scope, $element, $attrs) {},
templateUrl: "template.html",
compile: function(elm, attrs, ngModel){

var expFn = $parse(attrs.contentType + '.' + attrs.value);
return function(scope,elm,attrs){
scope.$parent.$watch(expFn, function(val){
scope.exp = { val: val };

if ( attrs.type == 'markdown'){
var converter = new Showdown.converter();
var html = converter.makeHtml(val);
//scope.exp.val = html;

ngModel.$setViewValue(html);
ngModel.$render();
}

})

scope.$watch('exp.val', function(val){
expFn.assign(scope.$parent, val)
})
}
}
}
})

这是一个适用于 Markdown 的过滤器,它在应用时起作用。(如果我能找到有条件地将它应用于现有指令的方法,我会考虑使用过滤器,但我宁愿使用 ng-model 来实现)

/*
app.filter('markdown', function ($sce) {
var converter = new Showdown.converter();
return function (value) {
var html = converter.makeHtml(value || '');
return $sce.trustAsHtml(html);
};
});
*/

这是指令模板

<div ng-class="{{css}}"
ng-click="view = !view"
ng-bind-html="exp.val">
</div>


<div>
<textarea rows="4" cols="30" ng-model="exp.val"></textarea>
</div>

这是正在使用的指令:

    <mb-text ng-cloak 
type="markdown"
content-type="product"
value="description"
class="test-one-text-2">
</mb-text>

最佳答案

为什么 ngModel 是空的?

  • 在指令上使用require 时, Controller 作为链接函数的第四个参数 传递。在您的代码中,您尝试将其作为编译函数的参数进行引用。 Controller 仅在链接阶段之前实例化,因此它永远不会被传递到编译函数中。

  • 更大的问题是require只能获取相同元素的 Controller ({ require: 'ngModel' }),或者父元素({ require: '^ngmodel' } ).但是您需要从子元素(在模板内)引用 Controller 。

如何获取ngModel

根本不要使用 require,因为你不能用它获取子元素的 Controller 。

来自 angular.element docs :

jQuery/jqLite Extras

controller(name) - retrieves the controller of the current element or its parent. By default retrieves controller associated with the ngController directive. If name is provided as camelCase directive name, then the controller for this directive will be retrieved (e.g. 'ngModel').

在链接函数中,您可以像这样控制 Controller :

 var ngModel = elm.find('textarea').controller('ngModel');

我修改了你的指令:

这是一个笨蛋:http://plnkr.co/edit/xFpK7yIYZtdgGNU5K2UR?p=preview

模板:

<div ng-class="{{css}}" ng-bind-html="exp.preview"> </div>

<div>
<textarea rows="4" cols="30" ng-model="exp.val"></textarea>
</div>

指令:

app.directive("myText", function($parse) {
return {
restrict: "E",
templateUrl: "template.html",
scope: {
css: "@class",
type: "@type"
},
compile: function(elm, attrs) {

var expFn = $parse(attrs.contentType + '.' + attrs.value);

return function(scope, elm, attrs) {

scope.exp = {
val: '',
preview: null
};

if (attrs.type == 'markdown') {
var converter = new Showdown.converter();

var updatePreview = function(val) {
scope.exp.preview = converter.makeHtml(val);
return val;
};

var ngModel = elm.find('textarea').controller('ngModel');
ngModel.$formatters.push(updatePreview);
ngModel.$parsers.push(updatePreview);
}

scope.$parent.$watch(expFn, function(val) {
scope.exp.val = val;
});

scope.$watch('exp.val', function(val) {
expFn.assign(scope.$parent, val);
});
};
}
};
});

关于javascript - Angularjs - ngModel.$setViewValue 不是函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21565493/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com