2013-10-01 42 views
2

我一直在考虑像Angularjs中的指令,像ASP.Net中的用户控件,也许我错了。了解Angularjs中的'指令'范例

用户控件允许您将一堆功能封装到可以放到任何地方的任何页面的小部件中。父页面不必向小部件提供任何内容。我很难得到指令去做任何接近于此的事情。假设我有一个应用程序,在用户登录后,我会在某处放置全局变量中的用户名/姓。现在,我想创建一个名为'loggedinuser'的指令并将其放入我想要的任何页面。它将呈现一个简单的div,其中包含从该全局变量中提取的登录用户的名称。我怎么做,而不必让控制器将这些信息传递给指令?我想在我看来这个指令的用法看起来很简单 < loggedinuser/>

这可能吗?

+0

不要在您的指令中创建一个独立的作用域,并在传递给您的指令的“链接”函数的作用域中查找所需的变量。或者如果您创建了一个独立的作用域,然后在父作用域中查找这些变量。 – akonsu

回答

2

我想你可以粗略地总结一下指令是什么“将一些功能封装到一个可以放到任何页面的小部件中的东西”,但除此之外还有更多。指令是通过创建新标签来扩展HTML的一种方式,允许您编写更多表现性标记。例如,您不必编写<div>和一堆<li>标签来创建评级控制,而是可以将其包装为新的<rating>标签。或者,而不是大量的<div> s和<span> S和诸如此类的东西来创建一个标签式界面,您可以实现一对指令,也就是说,<tab><tab-page>,并使用它们像这样:

<tab> 
    <tab-page title="Tab 1"> tab content goes here </tab-page> 
    <tab-page title="Tab 2"> tab content goes here </tab-page> 
</tab> 

这是真正的指令的力量,增强HTML。这并不意味着你只应该创建“通用”指令;你可以也应该制作特定于你的应用程序的组件。所以,回到你的问题,你可以实现一个<loggedinuser>标签来显示登录用户的名称,而不需要控制器提供信息。但是你绝对不应该依赖全局变量。该角的方式做这将是使用一种服务来存储这些信息,并将其注入指令:

app.controller('MainCtrl', function($scope, userInfo) { 
    $scope.logIn = function() { 
    userInfo.logIn('Walter White'); 
    }; 

    $scope.logOut = function() { 
    userInfo.logOut(); 
    }; 
}); 

app.service('userInfo', function() { 
    this.username = '' 
    this.logIn = function(username) { 
    this.username = username; 
    }; 
    this.logOut = function() { 
    this.username = ''; 
    }; 
}); 

app.directive('loggedinUser', function(userInfo) { 
    return { 
    restrict: 'E', 
    scope: true, 
    template: '<h1>{{ userInfo.username }}</h1>', 
    controller: function($scope) { 
     $scope.userInfo = userInfo; 
    } 
    }; 
}); 

Plunker here

如果你想开始创建强大的,可重用的指令,那么Angular dev guide on directives是一个必须去的地方。

+0

这是一个很好的答案,非常符合我的要求。谢谢! 我有一个后续问题:让我们说一下,在放置此指令的视图上发生了什么 - 可能是用户点击导致注销的东西 - 并且我希望指令更​​新并显示新文本。但是,没有导航发生在另一个视图上,我认为这意味着指令上的控制器功能不会重新运行,所以我需要该指令以某种方式对事件做出反应。我怎么能设置它? –

+0

没问题,伙计。很高兴我能帮上忙。 :)指令的控制器不会再运行,但添加到指令模板的插值 - {{user.name}} - 将被重新评估,并且其值将被更新。为了更好地理解它,请看一下[这里](http://docs.angularjs.org/guide/scope)。我会更新我的答案来说明这一点。 –

+0

为了清楚起见,假设我的loggedinuser指令放置在我的index.html文件中,以便它出现在每个视图上方的标题中。最初,没有登录的用户显示,所以它会隐藏自己。但是,在导航到我的登录视图并通过Web服务进行登录时,我希望该指令使用我的用户名更新(并显示)自己。由于指令的控制器只运行一次,允许更新指令范围的机制是什么?我相信那是我缺少的一部分。 –