解释$ apply和$ eval |我可以用其他功能替换它们吗? AngularJS

时间:2016-02-26 02:10:02

标签: javascript angularjs

我有一个stripe的指令,它将值a从指令传递给控制器​​。

指令

angular.module('stripe', []).directive('stripeForm', ['$window',
function($window) {
  var directive = { restrict: 'A' };
  directive.link = function(scope, element, attributes) {
    var form = angular.element(element);
    form.bind('submit', function() {
      var button = form.find('button');
      button.prop('disabled', true);
      $window.Stripe.createToken(form[0], function() {
        button.prop('disabled', false);
        var args = arguments;
        scope.$apply(function() {
          scope.$eval(attributes.stripeForm).apply(scope, args);
        });
      });
    });
  };
  return directive;

}]);

控制器:

angular.module('myApp', ['stripe'])
.controller('IndexController', function($scope, $http) {
  $scope.saveCustomer = function(status, response) {
    $http.post('/save_customer', { token: response.id });
  };
});

HTML

<form stripe:form="saveCustomer">
  <fieldset>
    <input type="text" size="20" data-stripe="number"/>
    <input type="text" size="4" data-stripe="cvc"/>
    <input type="text" size="2" data-stripe="exp-month"/>
    <input type="text" size="4" data-stripe="exp-year"/>
  </fieldset>
  <button type="submit">Save</button>
</form>

我的一个大学说使用$ eval不是最佳做法,所以我需要替代scope.$eval.

我也想知道指令如何将值传递给控制器​​。请解释代码,它是如何工作的。

scope.$apply(function() {
   scope.$eval(attributes.stripeForm).apply(scope, args);
});

参考:https://github.com/gtramontina/stripe-angular

1 个答案:

答案 0 :(得分:1)

是$ scope的最佳替代方案。$ apply,$ scope。$ eval,$ scope。$ digest是$ scope。$ evalAsync ..实际上它是最佳实践。那么什么是,以及$ evalAsync的用途:

$apply is already in progress

它基本上是$ apply(更加保证代码首先执行),但它会给你一个真正常见的错误:$digest is already in progress。与摘要相同:<div ng-app=""> <div ng-controller="Ctrl"> <button ng-click="count()">Inc counter</button> </div> <div ng-controller="EmptyCtrl"> </div> </div>

来自小提琴的evalAsync的代码示例:

<强> HTML

function EmptyCtrl() {

}
function Ctrl($scope) {
    $scope.counter = 0;
    $scope.count = function() {
        $scope.counter ++;
        console.log("setting value to "+$scope.counter)
    };

    var lastValue;
    $scope.$watch(function() {
        var value= $scope.counter;
        if (value!==lastValue) {
            lastValue = value;
            $scope.$evalAsync(function () {
                console.log("value in $evalAsync: "+value)
            });
        }
    });
}

<强>的Javascript

final Map<String, String> mss1 = new ProcessBuilder().environment();
mss1.entrySet()
        .stream()
        //depending on how you want to join K and V use different delimiter
        .map(entry -> 
        String.join(":", entry.getKey(),entry.getValue()))
        .forEach(System.out::println);

希望这有帮助!