【问题标题】:AngularJS - Pass value from isolated scope directive to another elementAngularJS - 将值从隔离范围指令传递给另一个元素
【发布时间】:2017-11-10 09:59:29
【问题描述】:

有没有办法将布尔值(dataLoading)从隔离范围指令传递到另一个元素,以便在登录操作期间加载数据时显示进度条?

index.html

<div class="progress-line" ng-show="dataLoading"></div>
<login-user email = "email" password = "password" show-nav-bar="showNavBar" recover-password="recoverPassword(email)" data-loading="dataLoading"></login-user>

login.component.js

angular
    .module('login')
    .directive('loginUser', [function() {
        return {
            scope: {
                email: '=email',
                password: '=password',
                showNavBar: '=showNavBar',
                dataLoading: '=dataLoading',
                recoverPassword: '&'
            },
            controller: 'LoginController',
            templateUrl: 'login/login.template.html',

        };
    }]);

login.controller.js

function recoverPassword(email) {
    console.log("recoverPassword email: " + email);
    $scope.dataLoading = true;
    authenticationService.recoverPassword(email, function (response) {
        console.log("Response success, status: " + angular.toJson(response.data.status) + " message: " + angular.toJson(response.data.message));
        $scope.message = response.data.message;
        $scope.dataLoading = false;
    });
}

【问题讨论】:

  • $broadcast 怎么样

标签: angularjs isolated-scope


【解决方案1】:

通常,让数据流向一个方向是一种更好的做法。 因此,dataLoading 变量的所有者应该是这两个组件的共同父级。

如果该布尔值的逻辑应该在user-login 组件中,您可以向它传递一个回调(通过&amp;),然后user-login 组件将在它开始获取数据时调用它,然后是父组件将更改该布尔值的值,并将其传播给相关的孩子。

const app = angular.module('app', []);

app.directive('parentComponent', function() {
    return {
      controllerAs: 'parentVM',
      controller: function() {
        this.isLoading = false;
        this.onLogin = () => {
          this.isLoading = true;
        }
      },
      template: '<div><child on-login="parentVM.onLogin()"></child><other-child is-loading="parentVM.isLoading"></other-child></div>'
    };
  })
  .directive('otherChild', function() {
    return {
      scope: {
        localLoading: '=isLoading'
      },
      template: '<div ng-class="{\'is-loading\':localLoading}">{{localLoading? \'Loading...\': \'\'}}</div>'
    }
  })
  .directive('child', function() {
    return {
      scope: {
        onLogin: '&'
      },
      template: '<button ng-click="onLogin()">Login</button>'
    };
  })
.is-loading {
  background-color: rgba(0, 200, 0, 0.2);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>

<div ng-app="app">
  <parent-component></parent-component>
</div>

【讨论】:

    【解决方案2】:

    您可以使用 EventEmitter 将数据发送到您的控制器。

    EventEmitter({loading: true })
    

    在您的组件上添加绑定以捕获更改:

    onDataChanges: '&'
    

    然后您在组件控制器上捕获数据:

    callbackdata(data) {
        this.loading= data.loading;
    }
    

    还有你的看法:

    <login ... onDataChanges="callbackdata($event)" ...></login>
    

    【讨论】:

      【解决方案3】:

      是的,当然。您可以创建一个公开“加载”属性的服务,然后将该服务注入到您的控制器和指令中。在您的指令中设置服务的“加载”属性。这就是你的指令。 现在将注入指令的相同服务注入到元素的控制器中。因此,如果该服务被称为 myloadingservice,您将执行类似 $scope.myloadingservice = myloadingservice 的操作。一旦你拥有了,你就可以直接绑定到元素中服务的加载属性,如下所示:ng-show="myloadingservice.loading"

      希望这会有所帮助。

      【讨论】:

      • 不要那样做。组件不应注入所有内容。它应该是独立的。大部分可重复使用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多