将ng-disabled参数设置为$ ionicPopup中的按钮

时间:2018-04-13 14:34:07

标签: javascript html angularjs ionic-framework

我试图创建一个$ ionicPopup,其中一个按钮在某些条件下被禁用(作为函数的返回值,让我们称之为status.capacity)。我想为此目的使用MyFunction()

问题是,我不知道如何以编程方式添加属性" ng-disabled"。

到目前为止我尝试了什么:

  • 在创建弹出窗口时添加属性,例如ng-disabled
  • 使用JavaScript =>创建弹出窗口后添加属性问题是attr:"ng-disabled='myFunction()'"方法是在实际显示弹出窗口之前执行的,所以我需要一种方法来检测弹出窗口何时打开,然后才执行该方法。
  • 在弹出模板中创建按钮作为html元素,而不是使用setAttribute()方法设置任何按钮。 这样可行,但我对此不满意因为我不想重新发明轮子"并重新定义了Ionic框架已经涵盖的按钮的CSS样式。

我的JS功能:

$ionicPopup.show()

2 个答案:

答案 0 :(得分:3)

TL; DR

$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. 我们可以在GitHub上为他们的项目做贡献,实现缺少的功能,为其编写测试,记录,提交问题,提取请求,要求发布更新的版本并使用更新版本。
  2. 这是理想的解决方案,因为它可以解决每个人的问题永远。虽然,确实需要一些时间。也许我会这样做。尽管如此,请随意自己做,并标记我,我会给你的公关+1

    1. 编写一段脏代码,用于修补特定情况下的特定问题
    2. 这不是理想的,但它现在可以正常工作

      我将探索并扩展下面的(快速&#39; n脏)选项#2

      修复

      到目前为止你尝试过的三件事:

      • 第一个根本不是一个东西(虽然它可能是我们实现它,测试它,记录并释放它)
      • 第三个是相当难以维护的(如你所知)

      这让我们看到你提到的第二件事:

        

      使用JavaScript

      创建弹出窗口后添加属性      

      问题是setAttribute()方法是在实际显示弹出窗口之前执行的,所以我需要一种方法来检测弹出窗口何时打开,然后才执行该方法。

      你是对的,但这只是双重问题的一部分。

      第1部分:按钮尚未创建

      实际上,当显示弹出窗口时,您可以将该呼叫延迟到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并挂钩自己那里。

      第2部分:Angular不了解新属性

      这里有很多关于此的内容,但它归结为以下内容: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

注意:应用您自己的样式/按钮对齐等

我希望它会对你有所帮助。