Adr*_*tev 81 javascript angularjs
我有一个复杂布局的应用程序,用户可以放置(拖放)小部件(通过从预定义的100多个小部件中选择),其中每个小部件都是一个显示一组数据的自定义实现(使用REST调用获取)以特定的方式.我已经阅读了大量的博客文章,stackoverflow问题和官方AngularJS文档,但我无法弄清楚我应该如何设计我的应用程序来处理那些要求.看看演示应用程序,有一个单独的模块(ng-app),当在.js文件中构建它时,依赖模块被声明为它的依赖项,但是我有一大组小部件,不知何故不建议全部描述它们那里.我需要建议以下问题:
编辑
有用的参考:
joa*_*mbl 61
这些只是一般性建议.
我应该如何设计我的应用程序和小部件 - 我应该有一个单独的AngularJS模块,或者每个小部件应该是主模块的指令吗?
你在谈论小部件,看起来很自然地将它们分成几个模块.有些小部件可能比其他小部件有更多共同之处.有些可能非常普遍,适合其他项目,有些更具体.
如果我将我的窗口小部件设计为指令,是否有一种方法可以在指令中定义依赖关系.也就是说我的指令在其实现中使用ng-calender?
依赖于其他模块的模块级完成的,但如果模块没有问题A取决于模块B和两个A并B取决于模块C.指令是在Angular中创建小部件的自然选择.如果指令依赖于另一个指令,则可以在同一模块中定义它们,或者在模块级别创建依赖关系.
如果我将每个窗口小部件设计为单独的模块,是否有办法将窗口小部件模块作为依赖项动态添加到主模块?
我不确定你为什么要这样做,我不知道该怎么做.指令和服务在Angular中使用之前未初始化.如果你有一个庞大的指令库(小部件),并且知道你可能会使用它们中的一些,但不是全部 - 但你不知道在应用程序初始化时会使用哪些指令你实际上可能"懒惰"加载模块加载后的指令.我在这里创建了一个例子
好处是,即使您有大量代码,也可以让应用程序快速加载,因为您不必在需要之前加载脚本.缺点是第一次加载新指令时可能会有相当大的延迟.
我应该如何设计控制器 - 每个小部件可能有一个控制器?
小部件可能需要自己的控制器.控制器通常应该很小,如果它们变大,你可以考虑是否有任何功能更适合服务.
如果我在视图中有相同类型的多个小部件,我应该如何分离状态(范围)?
需要范围变量的小部件毫无疑问应该有自己的隔离范围(scope:{ ... }在指令配置中).
使用AngularJS设计可重用小部件是否有最佳实践?
隔离范围,将依赖关系保持在必要的最小值.请参阅Misko关于Angular中最佳实践的视频
Brian Ford还撰写了一篇关于在Angular中编写大量应用程序的文章
bea*_*eek 17
这个问题对我来说也很重要.AngularJS主页上有几个例子(你可以称之为小部件),所以我通过他们的源代码试着看看他们如何分离他们的小部件.
首先,他们从未声明"ng-app"属性.他们使用
function bootstrap() {
if (window.prettyPrint && window.$ && $.fn.popover && angular.bootstrap &&
hasModule('ngLocal.sk') && hasModule('ngLocal.us') && hasModule('homepage') && hasModule('ngResource')) {
$(function(){
angular.bootstrap(document, ['homepage', 'ngLocal.us']);
});
}
}
Run Code Online (Sandbox Code Playgroud)
确保一切都正确加载.很好的想法,但奇怪的是,他们非常推动你的ng-app属性,甚至连自己都不使用它.无论如何这里是他们加载应用程序的主页模块 - http://angularjs.org/js/homepage.js
有一个名为appRun的指令
.directive('appRun', function(fetchCode, $templateCache, $browser) {
return {
terminal: true,
link: function(scope, element, attrs) {
var modules = [];
modules.push(function($provide, $locationProvider) {
$provide.value('$templateCache', {
get: function(key) {
var value = $templateCache.get(key);
if (value) {
value = value.replace(/\#\//mg, '/');
}
return value;
}
});
$provide.value('$anchorScroll', angular.noop);
$provide.value('$browser', $browser);
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
});
if (attrs.module) {
modules.push(attrs.module);
}
element.html(fetchCode(attrs.appRun));
element.bind('click', function(event) {
if (event.target.attributes.getNamedItem('ng-click')) {
event.preventDefault();
}
});
angular.bootstrap(element, modules);
}
};
})
Run Code Online (Sandbox Code Playgroud)
我将以ToDo列表为例.对于html,他们有
<div app-run="todo.html" class="well"></div>
Run Code Online (Sandbox Code Playgroud)
然后在页面的底部
<script type="text/ng-template" id="todo.html">
<h2>Todo</h2>
<div ng-controller="TodoCtrl">
<span>{{remaining()}} of {{todos.length}} remaining</span>
[ <a href="" ng-click="archive()">archive</a> ]
<ul class="unstyled">
<li ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.text}}</span>
</li>
</ul>
<form ng-submit="addTodo()">
<input type="text" ng-model="todoText" size="30"
placeholder="add new todo here">
<input class="btn-primary" type="submit" value="add">
</form>
</div>
</script>
Run Code Online (Sandbox Code Playgroud)
他们还有
<style type="text/css" id="todo.css"> //style stuff here </style>
<script id="todo.js"> //controller stuff here </script>
Run Code Online (Sandbox Code Playgroud)
使用了代码,但这些脚本上的id属性对于运行应用程序并不重要.这只是应用程序左侧的源代码显示.
基本上,他们有一个名为appRun的指令,它使用函数fetchCode
.factory('fetchCode', function(indent) {
return function get(id, spaces) {
return indent(angular.element(document.getElementById(id)).html(), spaces);
}
})
Run Code Online (Sandbox Code Playgroud)
获取代码.然后他们使用angular.bootstrap()来创建一个新的应用程序.他们也可以通过app-run加载模块.JavaScript项目示例初始化为
<div app-run="project.html" module="project" class="well"></div>
Run Code Online (Sandbox Code Playgroud)
希望这会有所帮助.我仍然不确定什么是"最佳"技术,但似乎AngularJS主页仅为每个示例/小部件使用完全独立的角度应用程序(ng-app).我想我会做同样的事情,除了改变fetchCode函数来获取AJAX的东西.
| 归档时间: |
|
| 查看次数: |
28475 次 |
| 最近记录: |