我有以下指令:
appDirective.directive('sidebar', function () {
var directiveDefinitionObject = {
//return {
restrict: 'E',
replace: true,
template: '<li ng-repeat="m in menu" ng-class="{\'dropdown\':m.submenu, \'open\':m.open}">' +
'<a href="{{m.url}}" ng-class="{\'dropdown-toggle\':m.submenu}" ng-attr-data-toggle="{{m.type}}">' +
'<i class="{{m.image}}"></i>' +
' {{m.name}}' +
'<b class="caret" ng-if="m.submenu"></b>' +
'</a>' +
'<ul ng-if="m.submenu" class="dropdown-menu">' +
'<li ng-repeat="s in m.submenu"><a ng-class="{\'active\':s.active}" href="{{s.url}}"><i class="{{s.image}}"></i> {{s.name}}</a></li>' +
'</ul>' +
'</li>',
link: function (scope, elem, attrs) {
scope.menu = [
{
"name": "Dashboard",
"url": "/manage/dashboard/index",
"image": "fa fa-dashboard",
"type": "dropdown",
"open": dashboardOpen,
"submenu": [
{
"name": "Overview",
"active": dashboard_overview_active,
"url": "/manage/dashboard/index",
"image": "fa fa-circle-o"
},
{
"name": "System Performance",
"active": dashboard_overview_nodes,
"url": "/manage/dashboard/nodes",
"image": "fa fa-tasks"
},
{
"name": "Query Performance",
"url": "/manage/dashboard/index",
"image": "fa fa-bolt"
}
]
},
{
"name": "Data Integration",
"url": "/manage/dataintegration/index",
"image": "fa fa-table"
},
{
"name": "User Management",
"url": "/manage/users/index",
"type": "dropdown",
"image": "fa fa-users",
"open": usersOpen,
"submenu": [
{
"name": "Users",
"active": users_users,
"url": "/manage/users/index",
"image": "fa fa-user"
},
{
"name": "Roles & Permissions",
"active": users_roles,
"url": "/manage/users/roles",
"image": "fa fa-lock"
},
{
"name": "Organizations",
"active": users_orgs,
"url": "/manage/users/organizations",
"image": "fa fa-globe"
}
]
},
{
"name": "Logs and Alerts",
"url": "/manage/logger/index",
"image": "fa fa-bars"
}
];
scope.$watch('menu', function(val) {
console.log(val);
$('.dropdown').on('show.bs.dropdown', function (e) {
$(this).find('.dropdown-menu').first().stop(true, true).slideDown();
});
$('.dropdown').on('hide.bs.dropdown', function (e) {
$(this).find('.dropdown-menu').first().stop(true, true).slideUp();
});
})
}
}
return directiveDefinitionObject;
});
我已经在指令实际绘制模板后运行的$watch
函数中添加了一些jQuery代码。但是,在将元素添加到DOM之前,$watch
会触发。
答案 0 :(得分:0)
这不是我们应该使用角度的方式。使用angular时,我们应该通过ng-click
和ng-change
等指令附加事件处理程序。
在您的情况下,当模型更改时,无法保证视图已完成渲染。该视图还会使用$watch
监听代码所做的模型更改。模型更改后,它会通知视图和您的代码 单独 。通常,使用$ timeout来安排下一个周期的工作是一个技巧。但我认为我们可以利用jQuery事件委托来处理动态元素。
尝试设置replace: false
并使用事件委派。不需要$watch
elem.on('show.bs.dropdown','.dropdown', function (e) {
$(this).find('.dropdown-menu').first().stop(true, true).slideDown();
});
elem.on('hide.bs.dropdown','.dropdown', function (e) {
$(this).find('.dropdown-menu').first().stop(true, true).slideUp();
});
在你的情况下使用$ watch还有另一个缺点,即可以将多个事件处理程序添加到同一个元素,因为每次模型更改时,此代码都将再次运行。