2016-03-07 40 views
0

我正在開發一個使用angularjs的應用程序,而且我也使用了指令,因爲一些UI在多個頁面中被重複使用。當我有一個依賴於promise的值的指令時,我必須使用$ scope。$ watch和一個if條件來檢查undefined,因爲指令在promise完成之前編譯。這裏有一個例子:

myAppModule.directive('topicDropdown', function() { 
     return { 
      templateUrl: 'Scripts/app/shared/dropdown/tmplTopic.html', 
      restrict: 'AE', 
      scope: { 
       subjectId: '=', 
       setDefault: '=', 
       topicId: '=' 
      }, 
      controller: [ 
       '$scope', 'service', function ($scope, service) { 

        $scope.$watch('subjectId', function() { 
         if ($scope.subjectId != undefined) 
          $scope.getTopics(); 
        }); 

        $scope.getTopics = function() { 
         service.get("section/topics/" + $scope.subjectId).then(function (data) { 
          $scope.listOfTopics = data; 
          if ($scope.setDefault) { 
           $scope.subjectId = $scope.listOfTopics[0].UniqueId; 
          } 

         }); 
        } 
       } 
      ] 
     } 
    }); 

的subjectId最終將來自一個承諾,但沒有$手錶,我會得到一個未定義的錯誤,因爲它會觸發getTopics沒有ID。

scope: { 
       subjectId: '=', 
       setDefault: '=', 
       topicId: '=' 
      }, 

目前,此代碼的工作,但我需要調用摘要週期,每次subjectId將通過一切環路範圍看變化。在這一點上,當主題ID發生變化時,我只在乎。

我也看到了一些使用ng-if的模板html的建議。事情是這樣的:

<div ng-if="subjectId != undefined"> 
    <topic-dropdown subject-id="subjectId"></topic-dropdown> 
</div> 

有了這個,我沒有使用$內,但是$看,我不知道這是最好的辦法要麼。

有沒有人有一個很好的解決這個問題?有沒有我可以使用的指令屬性,我不知道?

尼克

+0

爲什麼不將'subjectIdPromise'傳遞給指令呢?給它一個承諾,將解決你需要的價值,它應該都乾淨利落。 – Duncan

+0

爲什麼你在乎消化循環?性能問題?如果只有當值被定義時才需要讓http獲取,那麼保存$ watch取消註冊函數的返回值,並在完成註銷觀察者時調用它。 – fantarama

+0

@fantarama我關心的原因主要是表現問題和好奇心,看看是否有更好的方法或常見的做法。我沒有考慮取消註冊$ watch。 –

回答

0

傳遞一個承諾爲subjectId並getTopics等待它來解決。這將是這個樣子:

$scope.getTopics = function() { 
    $scope.subjectIdPromise.then(function (subjectId) { 
     $scope.subjectIdPromise = service.get("section/topics/" + subjectId) 
     .then(function (data) { 
      $scope.listOfTopics = data; 
      if ($scope.setDefault) { 
       return data[0].UniqueId; 
      } else { return subjectId; } 
     }); 
    }); 
}; 

這樣做,這樣所有進入subjectIdthen成功函數來完成。如果您想要更改subjectId,請用新的承諾替換承諾。

0

嘗試使用承諾的模式,

myAppModule.directive('topicDropdown', function() { 
    return { 
     templateUrl: 'Scripts/app/shared/dropdown/tmplTopic.html', 
     restrict: 'AE', 
     scope: { 
      subjectId: '=', 
      setDefault: '=', 
      topicId: '=' 
     }, 
     controller: [ 
      '$scope', 'service', function ($scope, service) { 

       $q.when($scope.subjectId).then(
      service.get("section/topics/" + $scope.subjectId).then(function (data) { 
        $scope.listOfTopics = data; 
        if ($scope.setDefault) { 
         $scope.subjectId = $scope.listOfTopics[0].UniqueId; 
        } 

       }); 
      ) 
     ] 
    } 
}); 

OR 

myAppModule.directive('topicDropdown', function ($q) { 
    return { 
     templateUrl: 'Scripts/app/shared/dropdown/tmplTopic.html', 
     restrict: 'AE', 
     scope: { 
      subjectId: '=', 
      setDefault: '=', 
      topicId: '=' 
     }, 
     link: function(scope, element, attrs){ 
     $q.when(subjectId).then(
      service.get("section/topics/" + scope.subjectId).then(function (data) { 
        scope.listOfTopics = data; 
        if (scope.setDefault) { 
         scope.subjectId = scope.listOfTopics[0].UniqueId; 
        } 

       }); 
      ) 
     } 
    } 
}); 

,但我認爲這樣或那樣的,你要使用$手錶。使用$ watch不會損害任何東西,它保持連接的角度。