Ham*_*mad 5 javascript angularjs angularjs-directive angularjs-scope
我想创建一个具有动态控制器的动态视图的指令.控制器和模板视图来自服务器.
指令
var DirectivesModule = angular.module('BPM.Directives', []);
(function () {
'use strict';
angular
.module('BPM.Directives')
.directive('bpmCompletedTask', bpmCompletedTask);
bpmCompletedTask.$inject = ['$window'];
function bpmCompletedTask ($window) {
// Usage:
// <bpmCompletedTask></bpmCompletedTask>
// Creates:
//
var directive = {
link: link,
restrict: 'E',
scope: {
type: '=',
taskdata: '=',
controllername:'@'
},
template: '<div ng-include="getContentUrl()"></div>',
controller: '@',
name: 'controllername'
};
return directive;
function link(scope, element, attrs) {
scope.getContentUrl = function () {
return '/app/views/TasksViews/' + scope.type + '.html';
}
scope.getControllerName = function ()
{
console.warn("Controller Name is " + scope.type);
return scope.type;
}
}
}
})();
Run Code Online (Sandbox Code Playgroud)
我在这里试图使用该指令
<div ng-controller="WorkflowHistoryController as vm">
<h2>Workflow History</h2>
<h3>{{Id}}</h3>
<div ng-repeat="workflowStep in CompletedWorkflowSteps">
<bpm-completed-task controllername="workflowStep.WorkflowTaskType.DataMessageViewViewName" taskdata="workflowStep.WorkflowTaskOutcome.TaskOutcome" type="workflowStep.WorkflowTaskType.DataMessageViewViewName">
</bpm-completed-task>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
现在的问题是当指令获取控制器名称时,它将其作为文字字符串而不是参数.
它可行吗?如果它不可行,用控制器创建动态视图并在ng-repeat中动态显示它们的最佳解决方案是什么?
谢谢,
更新20 Jan我刚刚更新了我的代码,以防有人对此感兴趣.所有信用都归@Meligy所有.
第一指令:
(function () {
'use strict';
angular
.module('BPM.Directives')
.directive('bpmCompletedTask', bpmCompletedTask);
bpmCompletedTask.$inject = ['$compile', '$parse'];
function bpmCompletedTask ($compile, $parse) {
var directive = {
link: function (scope, elem, attrs) {
console.warn('in the first directive - before if');
if (!elem.attr('bpm-completed-task-inner'))
{
console.warn('in the first directive');
var name = $parse(elem.attr('controllername'))(scope);
console.warn('Controller Name : ' + name);
elem = elem.removeAttr('bpm-completed-task');
elem.attr('controllernameinner', name);
elem.attr('bpm-completed-task-inner', '');
$compile(elem)(scope);
}
},
restrict: 'A',
};
return directive;
}
})();
Run Code Online (Sandbox Code Playgroud)
第二指令
angular
.module('BPM.Directives')
.directive('bpmCompletedTaskInner',['$compile', '$parse',
function ($window, $compile, $parse) {
console.warn('in the second directive');
return {
link: function (scope, elem, attrs) {
console.warn('in the second directive');
scope.getContentUrl = function () {
return '/app/views/TasksViews/' + scope.type + '.html';
}
},
restrict: 'A',
scope: {
type: '=',
taskdata: '=',
controllernameinner: '@'
},
template: '<div ng-include="getContentUrl()"></div>',
controller: '@',
name: 'controllernameinner'
};
}]);
Run Code Online (Sandbox Code Playgroud)
Html
<div ng-repeat="workflowStep in CompletedWorkflowSteps">
<div bpm-completed-task controllername="workflowStep.WorkflowTaskType.DataMessageViewViewName" taskdata="workflowStep.WorkflowTaskOutcome.TaskOutcome"
type="workflowStep.WorkflowTaskType.DataMessageViewViewName">
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
更新:
\n\n我成功了,但它真的很难看。查看:
\n\n\n\n您的示例有很多移动部分,因此这个示例很简单,但可以满足您的需求。
\n\n基本上,您需要一个包装器指令,它接受 JS 对象并转换为字符串属性,然后您可以使用 \xd9\x87\xd9\x89 指令来处理其他所有内容(模板、范围等)。
\n\n。
\n\n更新2:
\n\n内联代码:
\n\nvar app = angular.module(\'myApp\', []).\r\ndirective(\'communicatorInner\', ["$parse", "$compile",\r\n function($parse, $compile) {\r\n return {\r\n restrict: \'A\',\r\n template: "<input type=\'text\' ng-model=\'message\'/><input type=\'button\' value=\'Send Message\' ng-click=\'sendMsg()\'><br/>",\r\n scope: {\r\n message: \'=\'\r\n },\r\n controller: \'@\'\r\n };\r\n }\r\n]).\r\ndirective(\'communicator\', [\'$compile\', \'$parse\',\r\n function($compile, $parse) {\r\n return {\r\n restrict: \'E\',\r\n link: function(scope, elem) {\r\n if (!elem.attr(\'communicator-inner\')) {\r\n var name = $parse(elem.attr(\'controller-name\'))(scope);\r\n elem = elem.removeAttr(\'controller-name\')\r\n elem.attr(\'communicator-inner\', name);\r\n $compile(elem)(scope);\r\n }\r\n }\r\n };\r\n }\r\n]).\r\ncontroller("PhoneCtrl", function($scope) {\r\n $scope.sendMsg = function() {\r\n alert($scope.message + " : sending message via Phone Ctrl");\r\n }\r\n}).\r\ncontroller("LandlineCtrl", function($scope) {\r\n $scope.sendMsg = function() {\r\n alert($scope.message + " : sending message via Land Line Ctrl ");\r\n }\r\n})Run Code Online (Sandbox Code Playgroud)\r\n<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>\r\n\r\n<div ng-app="myApp">\r\n\r\n<div ng-init="test = {p: \'PhoneCtrl\', l: \'LandlineCtrl\' }">\r\n <communicator controller-name="test.p" message="\'test1\'"></communicator>\r\n <communicator controller-name="test.l"></communicator>\r\n\r\n</div>\r\n \r\n \r\n</div>Run Code Online (Sandbox Code Playgroud)\r\n。
\n\n原创(现在不相关,但可以帮助其他相关问题)
\n\n是的,它应该有效。
\n\nAngular 1.3 的测试:
\n\n\n\n需要检查的事项:
\n\n控制器是否已定义并添加到模块中?不起作用
\n\n如果控制器只是一个全局函数,它将无法工作。必须通过以下方式添加<myModule>.controller("<controllerName>", <functiion>)API添加
做ng-controller?只需将其添加到模板中即可
同样,直接在指令之外使用 ng-controller 是否有效?