2016-09-13 20 views
3

AngularJSコンポーネントのコンセプトを頭で包み込み、原理を理解し始めましたが、実際に試してみると、どのように実装するのか分かりませんコンポーネントと一緒に。AngularJS 1.5コンポーネントのDOM操作

リニアプログレスバーを実装する必要があります。テンプレートがあるため、論理的にはディレクティブではなくコンポーネントにする必要がありますが、コンポーネントでDOM操作を行う方法が見つからず、内部にディレクティブそのような小さなコンポーネント。ここでディレクティブの基本的な実装です:

JS

angular.module('test', []) 

.controller('MainCtrl', function($q, $scope) { 

    $scope.curVal= 0; 

    $scope.maxVal = 100; 

}) 

.directive('progressBar', [function() { 

    return { 
     restrict: 'E', 
     scope: { 
     curVal: '@', 
     maxVal: '@' 
     }, 
     template: "<div class='progress-bar'>"+ 
        "<div class='progress-bar-bar'>testing</div>"+ 
       "</div>",  

     link: function ($scope, element, attrs) { 

     function updateProgress() { 
      var progress = 0; 

      if ($scope.maxVal) { 
      progress = Math.min($scope.curVal, $scope.maxVal)/$scope.maxVal * element.find('.progress-bar').width(); 
      } 

      element.find('.progress-bar-bar').css('width', progress);   
     } 

     $scope.$watch('curVal', updateProgress); 
     $scope.$watch('maxVal', updateProgress);   
     } 
    }; 
}]); 

HTML

<progress-bar cur-val='{{curVal}}' max-val='{{maxVal}}'> 

CSS

.progress-bar { 
    width: 120px; 
    height: 18px; 
    border-style: solid; 
    border-width: 1px; 
    background-color: rgba(100,50,100,.60); 
    border-color: #aaa; 
} 

.progress-bar-bar { 
    width: 0px; 
    background-color: rgb(100,50,100); 
    height: 100%; 
    color: #fff; 
    font-weight: normal 
} 

だから、コンポーネントの原則を間違って理解していたのかもしれませんが、私は本当に面白いと思っていました。

私の質問は次のとおりです。何らかの方法でコンポーネントのDOMを操作できますか?答えがいいえの場合、コンポーネントでこのディレクティブを実装する方法は何ですか(そして、それはまったく適切ですか)。 CSSを変更するためにコンポーネントに指示を追加するのが適切な選択だとは思わないので、私は固執しています。

+1

'ng-style'を使用した場合、DOM操作やあなたのリンクのjsは必要ありません – charlietfl

+0

@charlietfl oops、実際にng-styleを使用してそこに値を渡すように見えます。 、ありがとう、私はあなたが答えとしてそれを投稿することができると思います – kemsbe

+0

あなたの指示を仕事にする必要がありますか、新しいコンポーネントのアプローチが必要ですか?チェックされた答えは命令のままであり、質問に答えません。 –

答えて

6

を見ますアプリケーションをどのように設計するかという問題があります。

MVC(MVVM、MVW、MV *)アーキテクチャを採用したい場合は、コンポーネントを持つことはほとんど意味がありません。ビューを作成するだけで、いくつかのDOM要素を変更または制御するコントローラとディレクティブによって制御されます。MV *アプリで

あなたが本当には、ページの残りの部分からブロックを分離しても、それを再利用可能にしたい場合があります。それでもコンポーネントを作ることはできますが、そのアーキテクチャーではディレクティブに固執する方が意味があります。

1.5以降では、ディレクティブはどのコンポーネントに非常に接近しています。あなたはスコープを取り除くことができ、コントローラを作成することができます...など、ちょうどもう少しの定型コードを書くことができます。

コンポーネントアーキテクチャ(反応する、Webコンポーネント、angular2 ...など)に従うようにするには、アプリケーション内のすべてがコンポーネントである必要があります。 (ログイン、ナビゲーション、フッターなど)、コンポーネントのコンポーネントを小さくすることができます。 (ファイルアップロードコンポーネントにプログレスバーコンポーネントが含まれる可能性があります)

さらにDOM要素の制御が必要な場合は、ディレクティブを使用します。 あなたのために既存の角度指令(ngStyle、ngClass、ngShow ...など)が動作しない場合は、あなたが作成します。

var progressBar = { 
    bindings: { 
    width: '<' 
    }, 
    template: `<div class="meter"> 
       <span ng-style="{ 'width' : $ctrl.width }"></span> 
      </div>` 
} 

https://plnkr.co/edit/rz8AVALGVl5EiZR1OUdK?p=preview

PS:

プログレスバーの事を答えるために(あなたはディレクティブを作成することができ、入力が自動的に焦点を当てる取得したいが)、これは私がそのコンポーネントを記述する方法を次のとおりです。 CSSスタイルはcss-tricksからコピーされて時間を節約しました。

+0

このような完全な答えをありがとう、今私が理解するように、角度1.xはコンポーネントアーキテクチャのためにかなり設計されていない、 ?そして、コンポーネント・アーキテクチャーの場合、反応や角度2のようなフレームワークがより適しています。正しいのですか?したがって、角度1.xの場合、ディレクティブに固執し、アプリの一部を分離する必要がある場合にのみコンポーネントを使用する方が良いでしょうか? – kemsbe

+1

@IlyaIlinいいえ、1.5から100%コンポーネントベースのアプリケーションを作成できます。それはあなた(またはあなたの上司)のみに依存しています。私たちが今年始めたすべてのアプリケーションは、コンポーネントベースになるでしょう(angular2はプロダクションの準備ができていません)。私たちのイントラネットは角度1.5のコンポーネントで100%作られています。いくつかのチームはより古い学校であり、私たちは他のいくつかのプロジェクトでMVCを採用しています。 (それについても何もショッキングなことです)意見の問題です。コンポーネントはよりモダンな(ファッション)ですが、コードはMVCで持っているものよりもはるかに洗練されています。 – gyc

+0

本当にありがとう、あなたは本当にそれをより明確にしました – kemsbe

3

Angularのドキュメンテーションによると、DOM操作は指令を使って行われるべきです(SHOULD)。現在は大きな作業になるかもしれませんが、プロジェクト内でいつでもディレクティブを再利用できます。

"ディレクティブは、AngularJSのHTMLコンパイラ($ compile)に指定された動作をそのDOM要素に付けるように指示する、DOM要素のマーカー(属性、要素名、コメントまたはCSSクラスなど)です例えばイベントリスナーを介して)、DOM要素とその子要素を変換することさえできます。

https://docs.angularjs.org/guide/directive

ここだあなたはディレクティブ

app.directive('changeStyle', function() { 
return { 
    restrict: 'AC', 
    link: function (scope, element, attrs) {   
     scope.$watch(attrs.myAttr, function (value) {  
     element.css('background-color', (value ? 'transparent' : attrs.myBgcolor));    
     });      
    } 
} 
を使用してCSSを変更する方法である

});

+0

ありがとう、私はまた、@ charlietflは、問題を解決するために2つの方法をngのスタイルを使用することができると思う – kemsbe

+0

あなたはまた、単純なCSSの変更 –

+0

私には@ JoaozitoPolo正しいですが、私は間違っている可能性があります私は正しい場合私は – kemsbe

1

たとえば、同様のコンポーネントを作成しました。スタイルの置き換えの定義を見てください:

テンプレート(myDiv.html):

<div class="bgDiv" style="color: {{ $ctrl.color }}"> 
    myDiv 
</div> 

を宣言しています。

component('myDiv', { 
    templateUrl: 'myDiv.html', 
    bindings: { 
     color: '=' 
    } 
}) 

使用するには、ディレクティブ対コンポーネントについてのあなたの混乱に対処するためにplunker

+0

ありがとう、それは実際に最も正しい答えを選択するのは難しいですが、あなたの1つは従属性を使用しないので、私はそれを正しいとマークするでしょう – kemsbe

+0

ああ、申し訳ありませんが、正しい回答を1つだけ選択してください – kemsbe

+0

心配しないでください。私はまた@gycの答えを好む、それはより説明され、コンポーネントを含んでいる –

関連する問題