对于想了解AngularJS——指令的复用的读者,本文将提供新的信息,我们将详细介绍angularjs指令的作用,并且为您提供关于angularjs与nodejs相关指令的复习、angularjs–A
对于想了解AngularJS—— 指令的复用的读者,本文将提供新的信息,我们将详细介绍angularjs指令的作用,并且为您提供关于angular js与node js相关指令的复习、angularjs – Angular – 在子指令的控制器中获取父指令的控制器(不是链接函数)、angularjs – angular.js:如何将ngclick从原始dom转移到指令的dom?、angularjs – angular指令的内容未呈现,除非您手动强制页面重排的有价值信息。
本文目录一览:- AngularJS—— 指令的复用(angularjs指令的作用)
- angular js与node js相关指令的复习
- angularjs – Angular – 在子指令的控制器中获取父指令的控制器(不是链接函数)
- angularjs – angular.js:如何将ngclick从原始dom转移到指令的dom?
- angularjs – angular指令的内容未呈现,除非您手动强制页面重排
AngularJS—— 指令的复用(angularjs指令的作用)
首先看一下一个小例子,通过自定义指令,捕获鼠标事件,并触发控制器中的方法。
单个控制器的标签指令
依然是先创建一个模块
var myAppModule = angular.module("myApp",[]);
在模块的基础上,创建控制器和指令
myAppModule.controller("myAppCtrl",["$scope",function($scope){ $scope.count = 0; $scope.loadData = function(){ $scope.count = $scope.count+1; console.log("myAppCtrl load data!"+$scope.count); } }]); myAppModule.directive("loader",function(){ return{ restrict:"AE", transclude:true, template:"<div><div ng-transclude></div></div>", link:function(scope,element,attr){ element.bind("mouseenter",function(){ // scope.loadData(); scope.$apply("loadData()"); }); } } });
首先看一下创建的控制器,在其中创建了一个 loadData 方法,用于相应触发事件,为了便于观察结果,添加了一个计数器。
下面的指令采用了属性和标签元素的使用方式:“AE”,为了得到效果,创建了一个内嵌的模板(避免没有内容时,点击不到)。
并在 link 属性的方法内,添加相应事件,方法中有三个参数:
1 scope,作用域,用于调用相应的作用域的方法。
2 element,指代创建的标签
3 attr,用于扩展属性,稍后展示使用方法
有了以上的准备工作,就可以在 body 里面使用标签了:
<div ng-controller="myAppCtrl"> <loader howToLoad="loadData()">第一个loader!</loader> </div>
如何复用指令
以上仅仅是单个控制器的指令使用,一个指令在一个页面中可以被多次使用,也就意味着,会有多个控制器使用该指令。
那么指令如何知道调用控制器的那个方法呢?这就用到了 attr 属性。
在创建指令时,调用 attr 获取属性的值
myAppModule.directive("loader",function(){ return{ restrict:"AE", transclude:true, template:"<div><div ng-transclude></div></div>", link:function(scope,element,attr){ element.bind("mouseenter",function(){ // scope.loadData(); // scope.$apply("loadData()"); scope.$apply(attr.howtoload); }); } } });
就可以在 body 中按照如下的方式使用了:
<div ng-controller="myAppCtrl"> <loader howToLoad="loadData()">第一个loader!</loader> </div> <div ng-controller="myAppCtrl2"> <loader howToLoad="loadData2()">第二个loader!</loader> </div>
需要注意的是:
1 标签中属性使用驼峰法命名,在指令中要转换成全部小写。
2 指令中调用的仅仅是属性的名字,没有方法括号。
3 应用时,属性对应的值是该控制器内声明的执行方法。
下面看一下样例代码:
<!doctype html> <html ng-app="myApp"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script> </head> <body> <div ng-controller="myAppCtrl"> <loader howToLoad="loadData()">第一个loader!</loader> </div> <div ng-controller="myAppCtrl2"> <loader howToLoad="loadData2()">第二个loader!</loader> </div> <script type="text/javascript"> var myAppModule = angular.module("myApp",[]); myAppModule.controller("myAppCtrl",["$scope",function($scope){ $scope.count = 0; $scope.loadData = function(){ $scope.count = $scope.count+1; console.log("myAppCtrl load data!"+$scope.count); } }]); myAppModule.controller("myAppCtrl2",["$scope",function($scope){ $scope.count = 0; $scope.loadData2 = function(){ $scope.count = $scope.count+1; console.log("myAppCtrl2 load data!"+$scope.count); } }]); myAppModule.directive("loader",function(){ return{ restrict:"AE", transclude:true, template:"<div><div ng-transclude></div></div>", link:function(scope,element,attr){ element.bind("mouseenter",function(){ // scope.loadData(); // scope.$apply("loadData()"); scope.$apply(attr.howtoload); }); } } }); </script> </body> </html>
实现的结果:
angular js与node js相关指令的复习
angular js自定义指令
定义一个指令本质上是在HTML中通过元素,属性,类或注释来添加功能,
MainModel.directive("myDirective",function () { return { restrict:"A",replace:true,template:'<p>cao</p>' } })这样一来 就可以直接使用<myDirective>这个了
接受两个参数 name 字符串,指令的名字 factory_name 函数 指令的行为
restrict 该选项默认的为A 其实有以下几项可选 分别为
元素E 属性A 类(C) 注释(M)
priority 也就是优先级 默认为0
template 至少的输出点 template也是可选的
当replace 为true时 输出为<p>value</p> 当为false时 输出就是<my-directive><p>cao</p></my-directive>
transclude 默认为false 翻译过来为嵌入ng-translude
详细可看该网站
http://www.cnblogs.com/Kavlez/p/4288885.html
node 中的next函数next函数主要负责将控制权交给下一个中间件,如果当前中间件没有终结请求,并且next没有被
调用,那么请求将被挂起,后边定义的中间件将得不到执行的机会。
详细请看这篇文章http://cnodejs.org/topic/5757e80a8316c7cb1ad35bab
angularjs – Angular – 在子指令的控制器中获取父指令的控制器(不是链接函数)
但是,我宁愿避免使用链接函数(和$scope all-together)并将所有代码都放在指令的控制器函数下.
angular.directive('parent',function(){ return { templateUrl: '/parent.html',scope: true,bindToController: true,controllerAs: 'parentCtrl',controller: function(){ this.coolFunction = function(){ console.log('cool'); } } } }); angular.directive('child',function(){ return { templateUrl: '/child.html',require: '^parent',controllerAs: 'childCtrl',controller: function() { // I want to run coolFunction here. // How do I do it? } } });
任何帮助表示赞赏!
controller: ($element) -> var parentCtrl = $element.parent().controller('parent'); parentCtrl.coolFunction(); //.......... //..........
这可能不是访问“任何”父控制器最透明的方式,因为它需要指令的特定名称,它是jqlite而不是纯Angular.
发现这个帖子很有用 – How to access parent directive’s controller by requiring it recursively?
编辑:感谢@Dmitry弄清楚角度不需要’.parent’来获得控制器.更新的代码 –
controller: ($element) -> var parentCtrl = $element.controller('parent'); parentCtrl.coolFunction(); //..........
angularjs – angular.js:如何将ngclick从原始dom转移到指令的dom?
将触发指令’可确认’的HTML代码
<span confirmable ng-click='users.splice($index,1)'></span>
指令:(coffeescript)
angular.module('buttons',[]) .directive 'confirmable',() -> template: """ <button> Destroy </button> """ replace: yes
所以我希望通过这个指令生成的最终结果是
<buttonng-click='users.splice($index,1)'> Destroy </button>
到目前为止,我已经在指令中使用了一个链接函数
angular.module('buttons',() -> template: """ <button> Destroy </button> """ replace: yes link: (scope,el,attrs) -> <---------- linking function $(el).attr 'ng-click',attrs.ngClick
但是我再次通过了指令文档,并发现了具有=,@和&操作符,但我真的不确定他们是否是我需要的.那么这是转载属性,我仍然需要理解,但在这一刻似乎也没有帮助.所以当我的链接功能现在的技巧,但我想我应该问,看看角是否提供了一个更优雅的解决方案.
谢谢!
我已经整理了一个Plunk here
(对不起,我喜欢JavaScript …所以这里)
这是你是父控制器.
app.controller('ParentCtrl',function($scope) { $scope.fooCalled = 0; $scope.foo = function() { $scope.fooCalled++; }; });
然后你的标记
<div ng-controller="ParentCtrl"> Foo Called: {{fooCalled}}<br/> <button ng-click="foo()">Call From Parent</button><br/> <custom-control custom-click="foo()"></custom-control> </div>
和你的指示声明:
app.directive('customControl',function(){ return { restrict: 'E',scope: { innerFoo: '&customClick' },template: '<button ng-click="innerFoo()">Call From Control</button>' }; });
指令定义中的范围声明中的位是将父作用域函数引用与指令的范围相关联,以便可以在单击时调用它.那就是&是在那里
angularjs – angular指令的内容未呈现,除非您手动强制页面重排
但是如果我调整屏幕大小(例如通过在此处折叠“开发人员工具”面板),则footable指令会自行绘制并适合面板:
重要的是,我遇到了与angular-c3图表指令相似的问题(它们加载错误,超出了hpanel的大小,但页面调整大小表现得很好),所以它可能不仅仅是一个破坏的指令.
你见过类似的东西吗?
细节:
下面是一个HTML模板,代表页面的非功能部分.我们有一个hpanel,里面有一张angular-footable directive ^1.0.3表,适用于它.
这是模板(toolList.html):
<div> <div> <div> <div> <divhttps://www.jb51.cc/tag/heading/" target="_blank">heading"> <div> <a><i></i></a> <ahttps://www.jb51.cc/tag/Box/" target="_blank">Box"><i></i></a> </div> Available tools. </div> <div> <input type="text"id="filter" placeholder="Search in table"> <table id="example1"data-page-size="8" data-filter=#filter> <thead> <tr> <th data-toggle="true">Id</th> <th>Class</th> <th>Label</th> <th>Description</th> <th data-hide="all">Owner</th> <th data-hide="all">Contributor</th> <th data-hide="all">Inputs</th> <th data-hide="all">Outputs</th> <th data-hide="all">Base command</th> <th data-hide="all">Arguments</th> <th data-hide="all">Requirements</th> <th data-hide="all">Hints</th> </tr> </thead> <tbody> <tr ng-repeat="tool in vm.tools"> <td><a ui-sref="tool-detail({id: tool.id})">{{tool.id}}</a></td> <td>{{tool.tool_class}}</td> <td>{{tool.label}}</td> <td>{{tool.description}}</td> <td>{{tool.owner}}</td> <td>{{tool.contributor}}</td> <td>{{tool.baseCommand}}</td> <td>{{tool.arguments}}</td> <td>{{tool.requirements}}</td> <td>{{tool.hints}}</td> </tr> </tbody> <tfoot> <tr> <td colspan="5"> <ul></ul> </td> </tr> </tfoot> </table> </div> </div> </div> </div> </div>
footable指令用于隐藏表的某些列,并在单击表行时显示它们.它还提供分页.它似乎不适用于页面加载,但当我调整页面大小并且屏幕大小超过媒体类型边距(因此从中等大小的屏幕变为大屏幕的引导css术语)时,会出现分页按钮,隐藏的列将被隐藏.
这是我在主模块app.js中导入footable指令的方法:
require("footable/js/footable"); require("footable/js/footable.filter"); require("footable/js/footable.striping"); require("footable/js/footable.sort"); require("footable/js/footable.paginate"); require("footable/css/footable.core.css") require("angular-footable"); angular.module("app",[ ...,"ui.footable",])
我使用webpack加载所有这些模块和bower来安装依赖项.
hpanel只是一个scss类,这里是它的定义:
/* Panels */ .hpanel > .panel-heading { color: inherit; font-weight: 600; padding: 10px 4px; transition: all .3s; border: 1px solid transparent; } .hpanel .hbuilt.panel-heading { border-bottom: none; } .hpanel > .panel-footer,.hpanel > .panel-section { color: inherit; border: 1px solid $border-color; border-top: none; font-size: 90%; background: $color-bright; padding: 10px 15px; } .hpanel.panel-collapse > .panel-heading,.hpanel .hbuilt { background: #fff; border-color: $border-color; border: 1px solid $border-color; padding: 10px 10px; border-radius: 2px; } .hpanel .panel-body { background: #fff; border: 1px solid $border-color; border-radius: 2px; padding: 20px; position: relative; } .hpanel.panel-group .panel-body:first-child { border-top: 1px solid $border-color; } .hpanel.panel-group .panel-body { border-top: none; } .panel-collapse .panel-body { border: none; } .hpanel { background-color: none; border: none; Box-shadow: none; margin-bottom: 25px; } .panel-tools { display: inline-block; float: right; margin-top: 0; padding: 0; position: relative; } .hpanel .alert { margin-bottom: 0; border-radius: 0; border: 1px solid $border-color; border-bottom: none; } .panel-tools a { margin-left: 5px; color: lighten($color-text,20%); cursor: pointer; } .hpanel.hgreen .panel-body { border-top: 2px solid $color-green; } .hpanel.hblue .panel-body { border-top: 2px solid $color-blue; } .hpanel.hyellow .panel-body { border-top: 2px solid $color-yellow; } .hpanel.hviolet .panel-body { border-top: 2px solid $color-violet; } .hpanel.horange .panel-body { border-top: 2px solid $color-orange; } .hpanel.hred .panel-body { border-top: 2px solid $color-red; } .hpanel.hreddeep .panel-body { border-top: 2px solid $color-red-deep; } .hpanel.hnavyblue .panel-body { border-top: 2px solid $color-navy-blue; } .hpanel.hbggreen .panel-body { background: $color-green; color: #fff; border:none; } .hpanel.hbgblue .panel-body { background: $color-blue; color: #fff; border:none; } .hpanel.hbgyellow .panel-body { background: $color-yellow; color: #fff; border:none; } .hpanel.hbgviolet .panel-body { background: $color-violet; color: #fff; border:none; } .hpanel.hbgorange .panel-body { background: $color-orange; color: #fff; border:none; } .hpanel.hbgred .panel-body { background: $color-red; color: #fff; border:none; } .hpanel.hbgreddeep .panel-body { background: $color-red-deep; color: #fff; border:none; } .hpanel.hbgnavyblue .panel-body { background: $color-navy-blue; color: #fff; border:none; } .panel-group .panel-heading { background-color: $color-bright; } .small-header .hpanel { margin-bottom: 0; } .small-header { padding: 0 !important; } .small-header .panel-body { padding: 15px 25px; border-right: none; border-left: none; border-top: none; border-radius: 0; // background: $color-bright; } .panel-body h5,.panel-body h4 { font-weight: 600; } .small-header .panel-body h2 { font-size: 14px; font-weight: 600; text-transform: uppercase; margin: 0 0 0 0; } .small-header .panel-body small { color: lighten($color-text,10%); } .hbreadcrumb { padding: 2px 0px; margin-top: 6px; margin-bottom: 0px; list-style: none; background-color: #fff; font-size: 11px; > li { display: inline-block; + li:before { padding: 0 5px; color: $color-navy-blue; } } > .active { color: lighten($color-text,20%); } } .wrapper { padding: 10px 20px; } .hpanel.collapsed .panel-body,.hpanel.collapsed .panel-footer { display: none; } .hpanel.collapsed .fa.fa-chevron-up:before { content: "\f078"; } .hpanel.collapsed .fa.fa-chevron-down:before { content: "\f077"; } .hpanel.collapsed.panel-collapse .panel-body { border-width: 0 1px 1px 1px; border-color: $border-color; border-style: solid; } .hpanel.collapsed .hbuilt.panel-heading { border-bottom: 1px solid $border-color; } body.fullscreen-panel-mode { overflow-y: hidden; } .hpanel.fullscreen { z-index: 2030; position: fixed; top: 0; left: 0; right: 0; bottom: 0; overflow: auto; margin-bottom: 0; } .hpanel.fullscreen .showhide { display: none; } .hpanel.fullscreen .panel-body { min-height: calc(100% - 77px); }
这是tool.module.js文件,它为模板设置动画:
import angular from "angular"; var ToolResource = require("workflow/tool/tool.service"); class ToolListController { // @ngInject constructor($location,$stateParams,$state,tools) { this.$location = $location; this.$state = $state; this.$stateParams = $stateParams; this.tools = tools; } } // @ngInject function routesList($stateProvider) { $stateProvider.state("tool-list",{ url: "/tool",parent: "layout",templateUrl: "/app/workflow/tool/toolList.html",controller: "ToolListController",controllerAs: "vm",data: { pageTitle: "Tool",pareDesc: "List of tools,available for workflow construction.",},resolve: { ToolResource: "ToolResource",tools: function(ToolResource) { return ToolResource.query().$promise; } } }); } module.exports = angular.module("tool",[]) .service('ToolResource',ToolResource) .controller('ToolListController',ToolListController) .config(routesList);
tool.service.js:
module.exports = function ToolResource($resource) { return $resource('/api/tool/:id',{id: '@id'}); }
回答:
社区真棒!
> 1.5年前,该指令已经创建
> 12天前,这个错误修复了by Alexryan in his fork
> 10天前我在StackOverflow上发布了这个问题
> 8天前,我在这个问题上放了一笔赏金
> 7天前ziscloud批准拉请求
>今天早上,赏金到期了,在不久的将来,Walfrat发现这个错误已得到修复
所以,是的,这是指令中的一个错误,它使它在从服务器获取数据之前绘制自己.使用bugfix我刚刚将load-when =“vm.tools”属性添加到指令中,它现在工作正常.
谢谢你,Alexryan,ziscloud,Walfrat和其他评论者/回答者. StackOverflow和Github刚刚结束了我的一天!
查看代码似乎你必须使用属性加载 – 如果你想延迟网格的初始化,即使你在你的状态中使用resolve属性,它也值得测试it.load-何时应该是启动时的空数组将在数组不再为空后触发加载,但绑定的数据将不会用于我所看到的初始化.
注意:我自己无法设置正确的plnkr,我不知道您正在使用的版本(以及使用哪个jQuery版本)和在线链接似乎不可用.
关于AngularJS—— 指令的复用和angularjs指令的作用的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于angular js与node js相关指令的复习、angularjs – Angular – 在子指令的控制器中获取父指令的控制器(不是链接函数)、angularjs – angular.js:如何将ngclick从原始dom转移到指令的dom?、angularjs – angular指令的内容未呈现,除非您手动强制页面重排等相关知识的信息别忘了在本站进行查找喔。
本文标签: