这是我的plunker和我无法开始工作的代码从第32行开始 http://plnkr.co/edit/pmCjQL39BWWowIAgj9hP?p=preview
我正在尝试将一个等效的markdown过滤器应用到一个指令上...我创建了过滤器并通过手动应用过滤器进行测试,并且它以这种方式工作,但我应该只在内容类型时有条件地使用过滤器on指令设置为markdown。
我试图通过更新ng-model>>>来实现这一目标。 ngModel.$setViewValue(html)
但我收到了错误
ngModel。$ setViewValue不是一个函数..这使得控制器无法被识别,尽管指令需要它。
这是一个有效的控制器:
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>
答案 0 :(得分:4)
ngModel
为空?在指令上使用require
时,控制器将作为第4个参数传递给链接函数。在您的代码中,您尝试将其作为编译函数的参数引用。控制器仅在链接阶段之前被实例化,因此无论如何它永远不会被传递到编译函数中。
更大的问题是require
只能获得相同元素({ require: 'ngModel' }
)或父元素({ require: '^ngmodel' }
)的控制器。但是您需要从子元素(模板内)引用控制器。
ngModel
?根本不要使用require,因为你无法使用它来获取子元素的控制器。
jQuery / jqLite Extras
controller(name) - 检索当前元素或其父元素的控制器。默认情况下,检索与ngController指令关联的控制器。如果name以camelCase指令名提供,则将检索该指令的控制器(例如'ngModel')。
在链接功能中,你可以像这样控制控制器:
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);
});
};
}
};
});