2017-10-03 3 views
0

AngularJSの新機能で、以前のアプリケーションでフレームワークを使っていくつかの作業をやり直そうとしました。私のアプリケーション(AngularJS v1.6.6)でモジュールがUIでポップアップを表示するために呼び出すメッセージボックスサービスを作成しようとしています。AngularJSコンポーネントのリファレンスサービス変数

サービスの変数をUI自体にバインドする方法がわかりません。私は、ローカルの 'MessageBox'変数をコントローラに作成し、その内容を参照するだけでなく、単に注入された変数を運がないものとして呼び出すことを試みました。私がサービスを通じてこれを達成できる方法はありますか?私はグローバル変数を考えていましたが、これに対してアドバイスを見ました。

サービスは最適なルートのように思えましたが、私はここでもっと理にかなった提案をしています。他のモジュールは自分自身のエラーメッセージや成功メッセージを表示する必要があるので、それを扱う標準的な方法を作る方が簡単だと思いました。

私のコードは、以下である:

メッセージbox.template.html

<div id="message" ng-show="$ctrl.MessageBox.display" style="background-color: white; border: 1px solid black; margin: 5px; float: right; top: 60px; right: 2%; padding: 5px; position: fixed; z-index: 100;"> 
 
    <img id="message-image" height="30" width="30" alt="{{ $ctrl.MessageBox.Image.alt }}" ng-src="{{ $ctrl.MessageBox.Image.source }}" /> <span id="message-text">{{ $ctrl.MessageBox.text }}</span> 
 
</div>

メッセージbox.module.js

angular.module("components.message-box", ["components"]) 
 
    .controller("MessageBoxController", ["$scope", "MessageBox", function MessageBoxController($scope, MessageBox) { 
 
    }]);

メッセージbox.component.js

/** 
 
* message-box.component.js 
 
* Contains the 'message-box' component 
 
*/ 
 
angular.module("components.message-box") 
 
    .component("messageBox", { 
 
     templateUrl: "/Scripts/cop/components/message-box/message-box.template.html", 
 
     controller: "MessageBoxController" 
 
    });

メッセージbox.service.js

/** 
 
* message-box.service.js 
 
* Defines the 'message-box' service 
 
*/ 
 

 
angular.module("components.message-box") 
 
    .service("MessageBox", function() { 
 
     var self = this; 
 

 
     self.display = false; 
 
     self.Image = { 
 
      alt: null, 
 
      source: null 
 
     }; 
 
     self.text = null; 
 
     self.timeout = null; 
 

 
     /** 
 
     * Hides the displayed message 
 
     * @public 
 
     */ 
 
     self.hideMessage = function() { 
 
      self.display = false; 
 
      self.timeout = null; 
 
      self.Image.alt = null; 
 
      self.Image.source = null; 
 
      self.text = null; 
 
     }; 
 

 
     /** 
 
     * Displays the provided message to the user 
 
     * @public 
 
     * @param {string} text Message text 
 
     * @param {Object} Image Image display data 
 
     * @param {number} [hideTimeoutMs=null] Number of miliseconds to wait before hiding the message 
 
     */ 
 
     self.showMessage = function (text, Image, hideTimeoutMs) { 
 
      self.text = text; 
 
      self.Image.alt = Image.alt; 
 
      self.Image.source = Image.src; 
 
      self.display = true; 
 

 
      // Cancel timer for current timeout if it exists 
 
      if (self.timeout !== null) { 
 
       self.timeout = null; 
 
      } 
 

 
      // Set a new timeout if specified 
 
      if (hideTimeoutMs !== undefined) { 
 
       self.timeout = setTimeout(self.hideMessage, hideTimeoutMs); 
 
      } 
 
     }; 
 
    });

ここでサービスを呼び出そうとする例を示します

visual.module.js

angular.module("core.visual", [ 
 
    "ngRoute", 
 
    "core.visual.settings" 
 
]) 
 
    .controller("VisualController", ["$routeParams", "$scope", "MessageBox", 
 
     function VisualController($routeParams, $scope, MessageBox) { 
 
      var self = this; 
 
      self.MessageBox = MessageBox; 
 
      
 
      self.MessageBox.showMessage("This is a message", "/Content/Images/loading.png", "Loading", 10000); 
 
     } 
 
    ]);

私としてもメッセージボックスを使用していない試しました成功していないローカルコントローラ変数 - これは私の最新の試みです。

私は適切なトラックにいますか?これも可能ですか?

答えて

0

私は答えを見つけるのを助けたthisの質問を見つけました。

以下はMessageBoxサービスの変更点です。私はサービス関数の呼び出し方法を変更せずにすべてを動作させることができました。

メッセージボックス。JS

/** 
 
* message-box.service.js 
 
* Defines the 'message-box' service 
 
*/ 
 

 
angular.module("components.message-box") 
 
    .factory("MessageBox", ["$rootScope", "$timeout", function ($rootScope, $timeout) { 
 
     var self = {}; 
 

 
     // Declare the Message variables 
 
     self.display = false; 
 
     self.imageSrc = null; 
 
     self.text = null; 
 
     self.timeout = null; 
 

 
     /** 
 
     * Hides the displayed message 
 
     * @public 
 
     */ 
 
     self.hideMessage = function() { 
 
      // Nullify all properties 
 
      self.display = false; 
 
      self.imageSrc = null; 
 
      self.text = null; 
 
      self.timeout = null; 
 
     }; 
 

 
     /** 
 
     * Displays the provided message to the user 
 
     * @public 
 
     * @param {string} text Message text 
 
     * @param {Object} imageSrc Image source location 
 
     * @param {number} [hideTimeoutMs=null] Number of miliseconds to wait before hiding the message 
 
     */ 
 
     self.showMessage = function (text, imageSrc, hideTimeoutMs) { 
 
      self.text = text; 
 
      self.imageSrc = imageSrc; 
 
      self.display = true; 
 

 
      // Set a new timeout if specified 
 
      if (hideTimeoutMs !== undefined) { 
 
       self.timeout = hideTimeoutMs; 
 
      } 
 
      else { 
 
       self.timeout = null; 
 
      } 
 

 
      // Broadcast changes 
 
      // Use a timeout so messages don't fail before controller instantiation 
 
      $timeout(function() { $rootScope.$broadcast("message:updated", self); }); 
 
     }; 
 

 
     return self; 
 
    }]);

最大の変化は、ここでタイムアウトを処理し、代わりに値を保持していません。メッセージは変更されたときにブロードキャストされ、以下のコントローラによって処理されます。

私はまだ一貫性のためにhideMessage()でローカル変数をクリアしています。 Angularがその値を({{}}を使って)動作させないようにする方法を理解できないので、私も 'alt'属性を削除しました。

ここで使用されている$ timeoutは、変更をブロードキャストする前に若干の遅延を追加します。場合によっては、showMessage()が(完全に構築される前に)コントローラ内で直ちに呼び出された場合にメッセージが表示されないことがあります。より大きいアプリケーションでは、これは十分ではないかもしれないが、これは比較的小さい。

変化の大部分は、コンポーネントのコントローラである。

メッセージbox.module.js

/** 
 
* message-box.module.js 
 
* Defines the 'components.message-box' module 
 
*/ 
 

 
angular.module("components.message-box", ["components"]) 
 
    .controller("MessageBoxController", ["$scope", "MessageBox", function MessageBoxController($scope, MessageBox) { 
 
     // Listen for message changes 
 
     $scope.$on("message:updated", function (evt, data) { 
 
      // Update global message variable 
 
      $scope.$apply(function() { 
 
       $scope.Message = data; 
 
      }); 
 
      // Check for a timeout 
 
      if (data.timeout !== null) { 
 
       setTimeout(function() { 
 
        $scope.$apply(function() { 
 
         data.hideMessage(); 
 
        }); 
 
       }, data.timeout); 
 
      } 
 
     }); 
 
    }]);

コントローラは、現在のメッセージ更新イベントをリッスン。それが起こると、コントローラは$ applyを使ってスコープの値を新しいメッセージに置き換え、UIも更新されます。同様に、メッセージが消える(該当する場合)ためのタイムアウト値を処理し、UIがメッセージを表示しないようにする必要があるため、$ applyも使用するようになりました。

メッセージbox.template.html

<div id="message" ng-show="Message.display" style="background-color: white; border: 1px solid black; margin: 5px; float: right; top: 60px; right: 2%; padding: 5px; position: fixed; z-index: 100;"> 
 
    <img id="message-image" height="30" width="30" alt="Information" ng-src="{{ Message.imageSrc }}" /> <span id="message-text" ng-bind="Message.text"></span> 
 
</div>

がうまくいけば、この中の誰かを助け(メッセージ-box.component.jsは変更されませんでした)同様の状況。この解決策は私のために働いていますが、これを処理するより良い方法があれば教えてください。

関連する問題