这是我遇到问题的二合一。
问题
我有一个滑块菜单,我在移动应用中创建了导航功能。菜单生成得很好,它被编译并显示出来。我可以轻弹前几个链接,然后按下后退,它将关闭,但是当我点击最后一个链接时,它根本不会关闭。它甚至没有回应。我必须重新启动应用程序,我打开检查器,它没有显示任何错误。所以我假设模板搞砸了,模板中没有错。提供商的源代码看起来似乎没问题,也许有订购问题?
其次。我将menuInstance
变量传递给需要它的所有区域,并且我试图设置一个自闭函数,但这也没有被识别。因此,所有这些可能共同构成一个非常酷的功能,但唉,没有什么工作正常,除了打开。
那么我如何让它识别它的实例,这样我就可以从它自己的控制器中关闭命令窗口,其次为什么在推送最后一个链接后它不能识别它自己。
这是菜单的小提琴,以便您可以看到行为:
https://jsfiddle.net/Mr_Pikachu/4brubsst/49/
当前源代码(严格模式)
/**
* Angular Slider Menu Widget
*/
// generate initial module and child modules
angular.module('sw.js.widget.slidermenu', ['ngAnimate', 'ngRoute']);
angular.module('sw.js.widget.slidermenu').directive('menuOverlayBackdrop', MenuOverlayBackdropDirective);
angular.module('sw.js.widget.slidermenu').directive('menuSlideCall', MenuSlideCallDirective);
angular.module('sw.js.widget.slidermenu').factory('$sliderMenuStack', SliderMenuStackFactory);
angular.module('sw.js.widget.slidermenu').provider('$sliderMenu', SliderMenuProvider);
// inject dependecies for each module as needed
MenuOverlayBackdropDirective.$inject = ['$sliderMenuStack'];
SliderMenuStackFactory.$inject = ['$document', '$compile', '$animate', '$rootScope'];
// create module functions
function MenuOverlayBackdropDirective($sliderMenuStack){
return {
compile : function(element, attrs){
element.addClass('widget-show');
return linkFn;
}
};
function linkFn(scope, element, attr){
scope.$on($sliderMenuStack.MENU_CLOSING, function(){
var instance = $sliderMenuStack.get();
instance.close(instance);
});
}
}
function MenuSlideCallDirective(){
return {
templateUrl : function(elem, attrs){
return attrs.templateUrl;
},
compile : function(element, attrs){
element.addClass('slide-left');
}
};
}
function SliderMenuStackFactory($document, $compile, $animate, $rootScope){
$menuStack = {
'MENU_CLOSING' : 'closing',
'MENU_CLOSED' : 'closed',
'instance' : null,
'menu' : null,
'open': function(menuInstance, menu) {
//console.log(menuInstance, menu);
//menuOpts.scope.main = menuOpts.menu.main;
var appendToEl = menu.appendTo;
var backdropEl = angular.element("<div class='widget-backdrop' menu-overlay-backdrop></div>");
var backdropScope = $rootScope.$new();
backdropEl.bind('click', function(){
backdropScope.$broadcast($menuStack.MENU_CLOSING);
});
var menuEl = angular.element("<div class='slider-menu-container' menu-slide-call template-url="+menu.template+"></div>");
menuInstance.backdropEl = backdropEl;
menuInstance.menuEl = menuEl;
menuInstance.scope = menu.scope;
menu.scope.close = menuInstance.close;
$menuStack.set(menuInstance);
$compile(menuEl)(menu.scope);
$compile(backdropEl)(backdropScope);
$animate.enter(backdropEl, appendToEl).then(function(){
$animate.enter(menuEl, appendToEl);
});
},
'close' : function(menuInstance){
menuInstance.scope.$apply(function(){
$animate.leave(menuInstance.menuEl).then(function(){
menuInstance.backdropEl.remove();
menuInstance = null;
$menuStack.set(menuInstance);
});
});
},
'set' : function(instance){
$menuStack.instance = instance;
},
'get' : function(){
return $menuStack.instance;
},
'remove' : function(){
$menuStack.instance = null;
}
};
return $menuStack;
}
function SliderMenuProvider(){
$menuProvider = {};
$menuProvider.options = {
background : true
};
$menuProvider.$get = ['$sliderMenuStack', '$q', '$rootScope', '$controller', '$document', function($sliderMenuStack, $q, $rootScope, $controller, $document){
return {
open : function(menuOptions){
var menu = {};
// preparing a new instance of the menu to be injected
var menuInstance = {
close : function(){
$sliderMenuStack.close(menuInstance);
}
};
menuOptions = angular.extend({}, $menuProvider.options, menuOptions);
var providedScope = menuOptions.scope || $rootScope;
menuScope = providedScope.$new();
// menuScope.$close = menuInstance.close();
menu.scope = menuScope;
menu.appendTo = $document.find('body').eq(0);
menu.template = menuOptions.templateUrl;
// generate the controller and then create an instance of the controller to be used
var ctrlInstantiate = $controller(menuOptions.controller, {$scope : menuScope}).constructor;
$sliderMenuStack.open(menuInstance, menu);
}
};
}];
return $menuProvider;
}
以下是我要加载的页面模板:
<main class='container-fluid'>
<div class='row'>
<section class='col-xs-12'>
<ul class='list-group headed-list-group'>
<ng-repeat ng-repeat='(k, track) in tracks'>
<li class='list-group-item list-group-heading'>{{k}}</li>
<li class='list-group-item title clearfix' ng-repeat="t in track">
<div class='col-xs-2'></div>
<div class='col-xs-8'>
<table class='track-table'>
<tr><td class='track-title'>{{t.name}}</td></tr>
<tr><td class='track-cat'>{{t.subtitle}}</td></tr>
<tr><td class='track-stats'></td></tr>
</table>
</div>
<div class='col-xs-2'>
<p class='text-center form-control-static text-right'>
<!--<i class='fa fa-ellipsis-v' downloads-drawer></i>-->
</p>
</div>
</li>
</ng-repeat>
</ul>
</section>
</div>
</main>
希望这指向了我想要去的方向。如果您需要更多源代码或有关错误集的信息,请快速评论,我会尽我所能。我想尽快解决这个问题。它困扰了我好几天,我想很快继续下一期。提前谢谢!
答案 0 :(得分:0)
因此,经过几个小时的阅读和一些代码实验后,我终于得到了工作解决方案!
您必须通过locals
选项将menuInstance注入控制器,然后相应地更新代码。我有下面的例子和工作小提琴。
<强>拨弄强>
https://jsfiddle.net/Mr_Pikachu/4brubsst/51/
<强>解强>
$ sliderMenu
<强>从强>
var ctrlInstantiate = $controller(menuOptions.controller, {$scope : menuScope).constructor;
以强>
var ctrlInstantiate = $controller(menuOptions.controller, {$scope : menuScope, $menuInstance : menuInstance}).constructor;
$ sliderMenuStack
<强>从强>
'close' : function(menuInstance){
menuInstance.scope.$apply(function(){
$animate.leave(menuInstance.menuEl).then(function(){
menuInstance.backdropEl.remove();
menuInstance = null;
$menuStack.set(menuInstance);
});
});
}
以强>
'close' : function(menuInstance){
$animate.leave(menuInstance.menuEl).then(function(){
menuInstance.backdropEl.remove();
menuInstance = null;
$menuStack.set(menuInstance);
});
}
menuOverlayBackdrop
将整个return语句更新为以下内容:
return {
compile : function(element, attrs){
element.addClass('widget-show');
return linkFn;
}
};
function linkFn(scope, element, attr){
scope.$on($sliderMenuStack.MENU_CLOSING, function(){
var instance = $sliderMenuStack.get();
instance.close(instance);
instance.scope.$apply(function(){
$animate.leave(instance.menuEl).then(function(){
instance.backdropEl.remove();
//menuInstance = null;
});
});
});
}
然后最后确保在调用提供程序时,在控制器函数中包含$menuInstance
注入变量,以确保一切正常。