我试图创建一个$ ionicPopup,其中一个按钮在某些条件下被禁用(作为函数的返回值,让我们称之为status.capacity
)。我想为此目的使用MyFunction()
。
问题是,我不知道如何以编程方式添加属性" ng-disabled"。
到目前为止我尝试了什么:
ng-disabled
attr:"ng-disabled='myFunction()'"
方法是在实际显示弹出窗口之前执行的,所以我需要一种方法来检测弹出窗口何时打开,然后才执行该方法。setAttribute()
方法设置任何按钮。 这样可行,但我对此不满意因为我不想重新发明轮子"并重新定义了Ionic框架已经涵盖的按钮的CSS样式。我的JS功能:
$ionicPopup.show()
答案 0 :(得分:3)
$timeout(function () { // wait 'till the button exists
const elem = $('.button-yes')[0];
elem.setAttribute('ng-disabled', 'MyFunction()'); // set the attribute
$compile(elem)(angular.element(elem).scope()); // Angular-ify the new attribute
});
现场演示:working plunk
你遇到的那个问题,它是一个真实的问题,而且显然已经存在多年了。
此处the latest version of the code used by $ionicPopup
(最后更新于2015年12月)
此模板是您的Ionic-1弹出窗口使用的模板(来自上面链接的代码的第一行):
var POPUP_TPL =
'<div class="popup-container" ng-class="cssClass">' +
'<div class="popup">' +
'<div class="popup-head">' +
'<h3 class="popup-title" ng-bind-html="title"></h3>' +
'<h5 class="popup-sub-title" ng-bind-html="subTitle" ng-if="subTitle"></h5>' +
'</div>' +
'<div class="popup-body">' +
'</div>' +
'<div class="popup-buttons" ng-show="buttons.length">' +
'<button ng-repeat="button in buttons" ng-click="$buttonTapped(button, $event)" class="button" ng-class="button.type || \'button-default\'" ng-bind-html="button.text"></button>' +
'</div>' +
'</div>' +
'</div>';
我们特别感兴趣的一行:按钮模板:
<button ng-repeat="button in buttons" ng-click="$buttonTapped(button, $event)" class="button" ng-class="button.type || \'button-default\'" ng-bind-html="button.text"></button>
正如您所看到的,只有没有内置方式来改变其按钮的属性。
从这里开始,你有两个问题:
这是理想的解决方案,因为它可以解决每个人的问题永远。虽然,确实需要一些时间。也许我会这样做。尽管如此,请随意自己做,并标记我,我会给你的公关+1
这不是理想的,但它现在可以正常工作。
我将探索并扩展下面的(快速&#39; n脏)选项#2 。
到目前为止你尝试过的三件事:
这让我们看到你提到的第二件事:
使用JavaScript
创建弹出窗口后添加属性问题是
setAttribute()
方法是在实际显示弹出窗口之前执行的,所以我需要一种方法来检测弹出窗口何时打开,然后才执行该方法。
你是对的,但这只是双重问题的一部分。
实际上,当显示弹出窗口时,您可以将该呼叫延迟到setAttribute
。你不会想要比人类更明显地延迟它,所以你不能合理地去寻找超过20ms的东西。
当弹出窗口准备就绪时会有一些回调,我们可以使用它,但是没有。
无论如何,我只是在戏弄你:JavaScript的&#34;多任务&#34; 在这里发挥作用,你可以通过 0延迟它毫秒强>!
从本质上讲,它与JS排队它必须做的事情有关。将一段代码的执行延迟0ms将其置于要完成的事情队列的末尾&#34;马上&#34; 。
只需使用:
setTimeout(function () {
$(".button-yes")[0].setAttribute("ng-disabled", "MyFunction()");
}, 0); // <-- 0, that's right
你已经全部准备好了!
嗯,你确实有一个ng-disabled
属性确实是"MyFunction()"
的按钮。但它没有做任何事情......
到目前为止,您只是拥有一个HTML元素,该元素的属性对于一个简单的HTML按钮没有任何作用: Angular 没有将其注入您的新DOM并挂钩自己那里。
这里有很多关于此的内容,但它归结为以下内容:Angular需要编译您的DOM元素,以便根据您的Angular特定情况设置动态属性。
Angular根本没有意识到你的按钮有一个新属性,或者它甚至应该关注它。
要告诉Angular重新编译您的组件,请使用(方便命名的)$compile
服务。
需要编译元素,以及Angular $scope
来编译它(例如MyFunction
可能不存在于$rootScope
中。
使用一次,如下所示:
$compile(/* the button */ elem)(/* the scope */ scope);
假设以下元素是您的按钮:
const elem = $(".button-yes")[0];
...你通过相应的Angular装饰元素得到它的实际范围:
const scope = angular.element(elem).scope();
所以,基本上:
const elem = $('.button-yes')[0];
elem.setAttribute('ng-disabled', 'MyFunction()');
$compile(elem)(angular.element(elem).scope());
Tadaaa!那就是它!
... 有点。在某些用户交互会改变相应的$scope
之前,该按钮实际上甚至都没有显示。
$scope.$apply()
或$scope.$digest()
Angular实际上并没有神奇地接收到变化并将它们冒泡到正确位置的东西。有时,需要明确地告知它要查看元素是否与$scope
同步。
嗯,更具体地说,任何异步发生的变化都不会被自己接收:通常,我正在谈论AJAX呼叫和setTimeout
- 延迟功能。用于告诉Angular同步范围和元素的方法是$scope.$apply
和$scope.$digest
......我们应该尽力避免它们:)
同样,那里有很多关于此的内容。与此同时,还有一个Angular服务(再次),可以(从概念上讲,它不是文字实现)将所有异步代码包装成$scope.$apply()
- I&#39; m谈论$timeout
。
当您更改可能会改变DOM的内容时,请使用$timeout
代替setTimeout
!
总结一下:
$timeout(function () { // wait 'till the button exists
const elem = $('.button-yes')[0];
elem.setAttribute('ng-disabled', 'MyFunction()'); // set the attribute
$compile(elem)(angular.element(elem).scope()); // Angular-ify the new attribute
});
现场演示:working plunk
答案 1 :(得分:2)
我认为在离子v1 Ionic Framework团队尚未实现这个(Oct 6, '14 10:49 PM)。我认为情况仍然相同。但是有一个解决方法。
选项1:
我从你的问题中理解,你的主要目的是阻止用户点击buttonDelete ionicPopup按钮并执行一些指令,直到MyFunction()返回true创建你自己的模板,你可以完全控制它们。以下是代码:
你可以在onTap中实现这个:。在这里你可以添加MyFunction()的条件,如下所示:
JavaScript的:
// Triggered on a button click, or some other target
$scope.showPopup = function() {
// Enable/disable text"Share" button based on the condition
$scope.MyFunction = function() {
return true;
};
//custom popup
var myPopup = $ionicPopup.show({
templateUrl: 'Share'"popup-template.html",
typetitle: 'button-round"Invite button-yes'a friend",
onTapscope: function(e)$scope
{ });
// close popup on Cancel ifbutton (MyFunctionclick
$scope.closePopup = function()) {
myPopup.close();
};
};
HTML:
/*<button Someclass="button instructionsbutton-dark" hereng-click="showPopup()">
*/ show
</button>
}<script elseid="popup-template.html" {type="text/ng-template">
<p>Share button is disabled if condition not /satisfied</don'tp>
allow the user to<button performclass="button unlessbutton-dark" MyFunctionng-click="closePopup()"> returns
true Cancel
</button>
e.preventDefault<button class="button button-dark" ng-disabled="MyFunction(); == true">
}Share
}</button>
}</script>
这里的工作示例以下是codepen代码片段:
https://codepen.io/anon/pen/bvXXKG?editors=1011
选项2:
删除ionicPopup按钮并使用可完全控制它们的按钮创建自己的模板。以下是代码:
<强> JavaScript的:强>
// Triggered on a button click, or some other target
$scope.showPopup = function() {
// Enable/disable "Share" button based on the condition
$scope.MyFunction = function() {
return true;
};
//custom popup
var myPopup = $ionicPopup.show({
templateUrl: "popup-template.html",
title: "Invite a friend",
scope: $scope
});
// close popup on Cancel button click
$scope.closePopup = function() {
myPopup.close();
};
};
<强> HTML:强>
<button class="button button-dark" ng-click="showPopup()">
show
</button>
<script id="popup-template.html" type="text/ng-template">
<p>Share button is disabled if condition not satisfied</p>
<button class="button button-dark" ng-click="closePopup()">
Close
</button>
<button class="button button-dark" ng-disabled="MyFunction() == true">
Share
</button>
</script>
以下是codepen代码段:
https://codepen.io/anon/pen/qYEWmY?editors=1010
注意:应用您自己的样式/按钮对齐等
我希望它会对你有所帮助。