Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度指令相关请求_Javascript_Angularjs_Directive - Fatal编程技术网

Javascript 角度指令相关请求

Javascript 角度指令相关请求,javascript,angularjs,directive,Javascript,Angularjs,Directive,我为以下小部件属性创建了自定义指令: <div widget></div> htmlTemplate是基本的html代码,也使用自定义指令(例如标记): 在响应处理程序中,我将结果绑定到范围。 我现在面临的问题是,该指令也请求数据,但该请求取决于从Offer.query()接收到的数据。 例如,来自Offer.query()的响应返回一个ID(我们称之为myID),seal指令需要该ID来请求更多数据。 因此,我只需将所有逻辑放在callback Offer.query

我为以下小部件属性创建了自定义指令:

<div widget></div>
htmlTemplate是基本的html代码,也使用自定义指令(例如
标记):

在响应处理程序中,我将结果绑定到范围。 我现在面临的问题是,该指令也请求数据,但该请求取决于从Offer.query()接收到的数据。 例如,来自Offer.query()的响应返回一个ID(我们称之为myID),seal指令需要该ID来请求更多数据。 因此,我只需将所有逻辑放在callback Offer.query回调函数中。这似乎不是最好的方法

所以我想把这部分移到
指令的link函数:

skdApp.directive("widget", function() {
  return {
    restrict: 'A',
    template: htmlTemplate,
    link: function($scope, element, attri) {
      /*
       * setup event handler and twitter bootstrap components here
       */
    }
  }
skdApp.directive("seal", function() {

  var sealHTML = '<div>{{offer.data.foobar}}</div>';

  return {
    restrict: 'E',
    template: sealHTML,
    link: function($scope, element, attrs) {

      $scope.$watch('offer.myId', function (newValue, oldValue) {

       if (typeof newValue !== "undefined") {

         /* request more data with myId 
          * and bind the result to offer.data
          */    

       }

      });

    }
});
skdApp.指令(“seal”,函数(){
var sealHTML='{{offer.data.foobar}}';
返回{
限制:'E',
模板:sealHTML,
链接:函数($scope,element,attrs){
$scope.$watch('offer.myId',函数(newValue,oldValue){
if(newValue的类型!=“未定义”){
/*使用myId请求更多数据
*并将结果绑定到offer.data
*/    
}
});
}
});

这种方法是“angular”兼容的,还是在angular中有其他更好的方法(在结构方面)来实现这一点?

您可以在child指令中查看offer.myId,因为父(小部件)和子(密封)共享相同的作用域。默认情况下,该指令不会创建新的作用域

我认为您可以广播自定义事件来通知child指令,并在需要时隔离作用域,以避免作用域碰撞


我将采用这种反向危险风格(以答案的形式提出的问题)。我一直在思考最近看到的这个问题的解决方案。它显然有效,但它有一些行为特征,我第一次尝试将其标记为“错误”.经过更深入的思考,我意识到在一些非常具体的场景中,这些特征可能是可取的

我当然不会将此作为一种通用解决方案,在每次需要绑定异步返回的数据时使用。我介绍它是为了强调这样一个事实,即此场景提出的问题有多个可能的答案。在某些情况下,可能需要真正的业务逻辑来阻止UI呈现,直到服务调用返回。在其他情况下,让UI保持活动状态并响应无关的工作可能更合适

例如,在订单处理系统中,我可能很想阻止客户端线程与视图元素交互,直到知道销售事务的结果为止。对于基于web的电子表格应用程序和服务器端公式计算,情况并非如此

我认为解决这一需求的异步和同步模式能够共存是一件美妙的事情。也就是说,返回承诺对象并没有强制客户机使用它,就像将返回值放在范围中强制客户机监视它们一样

下面的内容演示了一种与前面探讨的异步
watch()
样式同步处理此需求的方法:

var servicesModule = servicesModule || angular.module('myModule', []);

servicesModule.factory('thingClient', 
    ['$http', '$q', function( $http, $q ) {
        return new ThingClient($http, $q);
    }]
);

function ThingClient($http, $q) {
    function callService(scopeObject) {
        var defer = $q.defer();
        var promise = defer.promise;
        $http({
            method: 'POST',
            url: 'http://at/some/url/',
            data: { x: 'y', y: 'z', z: 'x', one: 1, two: 2, three: 3},
            cache: false
        }, function(data) {
            scopeObject.data = data;
            defer.resolve(data);
        }, function() {
            scopeObject.data = null;
            defer.resolve(null)
        });

        return promise;
    }
}
client-service.js

function ConsumingController( $scope, thingClient ) {
    // Be careful to use an object (so you have data wrapped such that it
    // is eligible for prototypical inheritance and call by reference without
    // passing the scope itself).  Leave the 'data' element undefined so you
    // can trigger the transition from undefined -> null in the failure case
    // and not just the on-success case. 
    $scope.dto = { data: undefined };
    var promise = thingClient.callService(scope.dto);

    // Asynchronous strategy
    $scope.$watch('offer.myId', function (newValue, oldValue) {
        if( newValue == null ) {
            // Fail!
        } else {
            // Succeed!
        }
    }

    // Synchronous strategy
    if( promise.then( 
        function(data) { 
            if( data == null ) { 
                // Fail
            } else {
                // Succeed
            }
        }
    }
}

使用controller.js

您将服务器交互封装到一个服务中,您的控制器很好而且“薄”,并且您的指令$watch()允许$scope更改以触发一些操作。我喜欢它。
var servicesModule = servicesModule || angular.module('myModule', []);

servicesModule.factory('thingClient', 
    ['$http', '$q', function( $http, $q ) {
        return new ThingClient($http, $q);
    }]
);

function ThingClient($http, $q) {
    function callService(scopeObject) {
        var defer = $q.defer();
        var promise = defer.promise;
        $http({
            method: 'POST',
            url: 'http://at/some/url/',
            data: { x: 'y', y: 'z', z: 'x', one: 1, two: 2, three: 3},
            cache: false
        }, function(data) {
            scopeObject.data = data;
            defer.resolve(data);
        }, function() {
            scopeObject.data = null;
            defer.resolve(null)
        });

        return promise;
    }
}
function ConsumingController( $scope, thingClient ) {
    // Be careful to use an object (so you have data wrapped such that it
    // is eligible for prototypical inheritance and call by reference without
    // passing the scope itself).  Leave the 'data' element undefined so you
    // can trigger the transition from undefined -> null in the failure case
    // and not just the on-success case. 
    $scope.dto = { data: undefined };
    var promise = thingClient.callService(scope.dto);

    // Asynchronous strategy
    $scope.$watch('offer.myId', function (newValue, oldValue) {
        if( newValue == null ) {
            // Fail!
        } else {
            // Succeed!
        }
    }

    // Synchronous strategy
    if( promise.then( 
        function(data) { 
            if( data == null ) { 
                // Fail
            } else {
                // Succeed
            }
        }
    }
}