控制器与指令分开?

时间:2015-09-24 16:46:38

标签: javascript angularjs

这里有角度的新手。我正在创建一个top-nav指令,如下所示:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="department narrow-option">
    <div class="mobile-inner toggle"> <a href="#" class="toggle-this"><h3>Department:</h3> <h4>Any</h4></a>

    </div>
    <div class="additional-info hide">
        <div class="selected-options" id="department-selections">
            <ul>
                <li><a href="#" title="All" class="option-btn default">All</a>

                </li>
                <li><a href="#" title="Department 1" class="option-btn">Department 1</a>

                </li>
                <li><a href="#" title="Department 2" class="option-btn">Department 2</a>

                </li>
                <li><a href="#" title="Department 3" class="option-btn">Department 3</a>

                </li>
            </ul>
        </div>
        <!-- eo // selected-options -->
    </div>
    <!-- eo // additional-info -->
</div>
<!-- eo // department -->

这很好用。但是,我想说我在top-nav之外有一个按钮需要在topNav的控制器中调用showLoginDialog()方法。

为了实现这一点,我需要将控制器与top-nav隔离开来,如下所示:

<html>
<body ng-app="myApp">
    <top-nav></top-nav>
</body>
</html>

我的问题是:这被认为是不好的做法吗?也就是说,从指令中删除控制器,以便外面的东西可以访问它?

编辑:仅供参考 - 我的&#34;登录弹出窗口&#34;单击&#34;登录&#34;我的top-nav中的按钮。但是,我也想要这个&#34;登录弹出窗口&#34;当点击巨人&#34;注册&#34;时能够弹出我的主页上的按钮。这就是为什么我问过如何从外面打电话。

3 个答案:

答案 0 :(得分:3)

如果def weather_forecast(arg): dt_list = [] temp_list = [] humidity_list = [] description_list = [] for d in arg['list']: dt_list.append(d['dt']) temp_list.append(d['main']['temp']) humidity_list.append(d['main']['humidity']) description_list.append(d['weather'][0]['description']) date = dt_time(dt_list) temp = tempF(temp_list) humidity = humidity_percent(humidity_list) description = desc_func(description_list) mdict = OrderedDict((z[0],list(z[1:])) for z in zip(date, temp, description)) for k,v in mdict.items(): print("{}: {}".format(k,v)) def dt_time(arg): date = [] for item in arg: x = datetime.datetime.strptime(time.ctime(item), "%a %b %d %H:%M:%S %Y") y = str(x) date.append(y) return date def tempF(arg): temp = [] for item in arg: t = "%s F" % item temp.append(t) return temp def humidity_percent(arg): humidity = [] for item in arg: h = "%s%%" % item humidity.append(h) return humidity def desc_func(arg): desc = [] for item in arg: desc.append(item.encode("utf-8")) return desc 是不在同一层次结构中存在的组件的通用功能,那么我发现如果您只是实现一项服务就不那么令人头疼了:

showLoginDialog

在您提供的示例中,不会有任何范围继承,因此您无法从app.factory('login', function() { return { showLoginDialog: function() { // whatever } }; }); 访问该方法。但是,如果您在服务/工厂中放置常用方法和属性,那么您现在已经为自己提供了一种机制,通过该机制,您可以在应用程序中共享单一事实来源以获取信息。这是更多&#34; Angular-ish&#34;这样做的方法。

修改

要在控制器中使用该服务,只需注入它:

topNav

取决于您的应用的结构,但虽然机制可能会发生变化,但政策也会相同。

答案 1 :(得分:2)

使用ng-controller扩展范围是不好的做法。

http://teropa.info/blog/2014/10/24/how-ive-improved-my-angular-apps-by-banning-ng-controller.html

如果你移动指令怎么办?您需要继续在视图的不同部分应用ng-controllers,这会让您感到困惑。

指令和控制器可以通过两种方式相互通信。其中一个Josh Beam已经回答了哪个是使用服务。另一种是使用$ broadcast和$ emit / $。

使用$ broadcast,$ emit,$ on。

的Angular自定义事件

对于您提供的示例,我将在父控制器范围内使用一个函数来触发指令的showLoginDialog函数。

$rootScope.$broadcast('showLogin', data)

然后在你的指令控制器中

$rootScope.$on('showLogin', function(e, args){
   // do stuff
});

您还必须取消注册$ rootScope侦听器以避免内存泄漏。你这样做的方法是调用$ on返回的函数并在范围的$ destroy事件中应用它。

var cleanfunction = $rootScope.$on('showLogin', showLoginDialog());

$scope.$on('$destroy', function(){
  cleanfunction();
})

答案 2 :(得分:0)

我不能说这是糟糕的练习,但它没有意义。如果您需要一个可在其外部访问的指令的方法,那么该方法不属于那里。

该方法应该在上面,也许在父控制器/组件内部。