何时使用指令,当一个服务和一个控制器在angularjs?

时间:2015-06-30 09:40:11

标签: javascript angularjs

我对何时使用angularjs中的内容感到有点困惑。我知道控制器,服务/工厂和指令的基本概念,但我不确定在我的情况下使用什么。

场景:允许用户发布链接的表单。表单本身从外部服务请求有关链接的一些信息,并立即将其呈现给用户。可以通过NodeJS应用程序的API发布(不重要)。表单应该是可重用的,所以我希望代码是干的。我不喜欢使用ng-include,因为指令似乎是要走的路。

到目前为止,我有一家工厂处理请求信息(linkservice)和工厂处理创建帖子(posts)。然后我使用它自己的控制器指令来显示表单并处理用户操作。但是我不确定我是否应该移动指令的内容'控制器进入普通控制器甚至服务,因为指令不应该处理请求数据(据我所知)。或者这可能是正确的方式。

指令

// The form to publish a new post
myModule.directive('postForm', [
  'linkservice',
  'posts',
  '$state',
  function(linkservice, posts, $state){
  return {
    templateUrl : '/js/app/views/partials/post-form.html',
    controller: function ($scope) {
      $scope.analyzeURL = function() {
        $scope.filtered_url = $scope.link.url.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?/gmi);
        if($scope.filtered_url !== null) {
          linkservice.extractURL($scope.filtered_url).then(function(res) {
            var website_info = res.data;
            $scope.link = {
              title: website_info.title,
              description: website_info.description,
              medium: website_info.provider_name,
              medium_thumbnail_url: website_info.favicon_url,
              url: $scope.filtered_url[0]
            }
            // Image
            if(website_info.images.length > 0 && website_info.images[0].width >= 500) {
              $scope.link.thumbnail_url = website_info.images[0].url;  
            } else { $scope.link.thumbnail_url = null; }
            // Keywords
            $scope.link.keywords = [];
            if(website_info.keywords.length >= 2) {
              $scope.link.keywords[0] = website_info.keywords[0].name;
              $scope.link.keywords[1] = website_info.keywords[1].name;
            }
            $scope.show_preview = true;
          });
        }
      },
      // addPost
      $scope.addPost = function(){
        if(!$scope.post || $scope.post.text === '' || !$scope.link || $scope.link.url === '') { return; }
        posts.create({
          post: $scope.post,
          link: $scope.link
        }).success(function() {
          delete $scope.post;
          delete $scope.link;
        });
      }
    }
  }
}]);

模板

<form ng-submit="addPost()" style="margin-top:30px;">
  <h3>Add a new Post</h3>
  <div class="form-group">
    <input type="text"
      class="form-control"
      placeholder="URL"
      ng-model="link.url" ng-change="analyzeURL()"></input>
  </div>
  <div class="form-group">
    <textarea type="text"
    class="form-control"
    placeholder="Description / TLDR"
    ng-model="post.text" ></textarea>
  </div>
  <div class="form-group">
    <button type="submit" class="btn btn-primary">Post</button>
  </div>
  <div class="form-group">
    <input type="hidden" ng-model="link.title"></input>
    <input type="hidden" ng-model="link.description"></input>
    <input type="hidden" ng-model="link.thumbnail_url"></input>
    <input type="hidden" ng-model="link.medium"></input>
    <input type="hidden" ng-model="link.medium_thumbnail_url"></input>
    <input type="hidden" ng-model="link.keywords"></input>
  </div>
  <div class="lp-container" ng-show="show_preview">
    <span class="lp-provider"><img src="{{link.medium_thumbnail_url}}" class="lp-favicon">&nbsp;{{link.medium}}</span>
    <h2 class="lp-title">{{link.title}}</h2>
    <div class="lp-description">{{link.description}}</div>
    <img class="lp-thumbnail" ng-show="link.thumbnail_url" src="{{link.thumbnail_url}}">
    <div class="lp-keywords">
      <span ng-repeat="kw in link.keywords" class="lp-keyword">{{kw}}</span>
    </div>
  </div>
</form>

1 个答案:

答案 0 :(得分:1)

最好的方法是记住Angular是一个类似MVVM的框架。

指令定义视图,如何打印数据,事件等。

您的服务单身,因此它们是存储数据并放置所有数据管理(Web服务请求等)的最佳位置。因为它们只会被实例化一次,所以您的数据不会重复。

每次将它们链接到指令(ng-controller等)时,

控制器都会被实例化。所以你应该避免在这里存储数据。控制器应该用作服务和指令之间的链接。它们可能包含低级数据检查等,然后调用服务。

在您的示例中,您可以通过将控制器移动到另一个位置来简化代码,以避免混淆所有代码。例如:当你的指令只是需要它的控制器时,你的指令直接依赖于linkservice