2017-06-21 17 views
1

私は完全に狂っているような問題があります!私は親スコープ変数から値を取るスコープにバインドされた属性を取るディレクティブを使用します。 ... console.log(スコープ)を除いて、属性は通常、スコープオブジェクトのプロパティとして期待値で表示されますが、console.log(scope.myAttr)を実行すると定義されません!!角度指示スコープは、リンク機能に渡す/渡さない

このような人は誰ですか?

// In parent directive: 
 

 

 
scope.datepickerOptions.enableTime = false; 
 

 

 

 

 
// In directive: 
 

 
angular.module('myModule') 
 
\t .directive('datepicker', function() { 
 
\t \t return { 
 
\t \t \t require: 'ngModel', 
 
\t \t \t restrict : 'A', 
 
\t \t \t scope: { 
 
\t \t \t \t format: '@', 
 
\t \t \t \t enableTime: '=', 
 
\t \t \t \t minDate: '@', 
 
\t \t \t \t maxDate: '@', 
 
\t \t \t \t mode: '@' 
 
\t \t \t }, 
 
\t \t \t link : function(scope, element, attrs, ngModel) { 
 
\t \t \t \t console.log("scope") 
 
\t \t \t \t console.log(scope) 
 
\t \t \t \t // displays all properties with expected values 
 
       //=> scope.enableTime: false 
 

 
\t \t \t \t console.log("enableTime") 
 
\t \t \t \t console.log(scope.enableTime) 
 
     // undefined (!!!) 
 
     
 
     
 
     ...
// In parent template: 
 

 
... 
 

 
<input 
 
    type="text" 
 
    id="events_date" 
 
    name="events_date" 
 
    ng-model="events.selectedDate" 
 
    placeholder="Select Date Range" 
 
    ng-change="setQueryDate()" 
 
    format="d M Y" 
 
    mode="range" 
 
    enable-time="datepickerOptions.enableTime" 
 
    max-date="today" 
 
    datepicker> 
 
    
 
    
 
    ...

私も試してみました: '@'

をし、私が行うとき、私は同じ狂気を取得:enableTimeで有効時= "{{datepickerOptions.enableTime}}" console.log(attrs)とconsole.log(attrs.enableTime)

$ scope引数を持つコントローラーを置いたときと同じこと: console.log($ scope)displayすべて正常ですが、console.log($ scope.enableTime)は未定義です

+0

「attrs」を使ってみてください。リンク機能が実行されると、スコーププロパティはまだ設定されていません。それはその後に設定されます。そのため、直接参照しようとすると「未定義」になってしまいます。コンソールのスコープオブジェクトには、スコープの最終状態が表示されます。 – Hoyen

+0

実際に 'scope'オブジェクトを使用する必要がある場合は、link関数の代わりにdirectiveのコントローラ関数を使用してください。 – Hoyen

+0

しかし、attrs.enableTimeには「datepickerOptions.enableTime」という値はありませんか?プロジェクトの他のディレクティブがすべて正常に機能するのはなぜですか?それは**制限です: 'A' **これはこの動作ですか? –

答えて

0

あなたの指示にスコープ変数はありません。あなたはscope変数として任意の属性値を保持したい場合は、ちょうどこのような何か:私は何が起こっているかと思います

scope.yourVariable = attrs.yourAttribute; 
+0

どういう意味ですか? 範囲:{ \t \t \t \t形式: '@'、 \t \t \t \t enableTime: '='、 \t \t \t \t MinDateプロパティ: '@'、 \t \t \t \t maxDateの:「このすべては何ですか@」、 \t \t \t \tモード: '@' \t \t \t}、 ?? –

+0

@DimitrisPapazacharias、これは単なる指示ですが、**スコープ変数**を宣言していません。だから、 'attrs.neededAttribute'のような' attrs'パラメータを使って属性にアクセスすることができます。または、この属性をスコープに追加する場合は、 'scope.yourVariable = attrs.neededAttribute'を実行する必要があります。 –

1

はディレクティブが作成された後、あなたがenableTimeを設定しているということです。そのような場合は、 'ng-if'ディレクティブを使用して、ロード前に最初に定義されているかどうかを確認できます。ここで

は、私が起こっていると思うものの例です:

var app = angular.module('test', []); 
 

 
app.controller('MainCtrl', function($scope, $timeout) { 
 
    $scope.datepickerOptions = {} 
 
    $timeout(function() {  
 
    $scope.datepickerOptions.enableTime = false; 
 
    }, 500); 
 
}); 
 
app.directive('datepicker', function() { 
 
    return { 
 
    restrict: 'A', 
 
    scope: { 
 
     enableTime: '=' 
 
    }, 
 
    link: function(scope, element, attrs, ngModel) { 
 
     console.log("scope") 
 
     console.log(scope) 
 
     // displays all properties with expected values 
 
     //=> scope.enableTime: false 
 

 
     console.log("enableTime") 
 
     console.log(scope.enableTime) 
 
    } 
 
    } 
 
});
<!DOCTYPE html> 
 
<html ng-app="test"> 
 

 
<head> 
 
    <script data-require="[email protected]" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script> 
 
    <script src="app.js"></script> 
 
</head> 
 

 
<body ng-controller="MainCtrl"> 
 
    <input datepicker ng-if="datepickerOptions.enableTime != null" enable-time="datepickerOptions.enableTime" /> 
 
</body> 
 
</html>

+0

私は最終的に$ timeout()内でいくつかのscope.variables初期化をラップする問題を解決しましたが、クリーンな解決策のようには感じません。私はこれまでにこれまでに遭遇したことはありません。本当の疑問は、私が使用する他のすべての指示が、そのように振る舞わない理由です。 –

+0

@DimitrisPapazacharias本当にコードに依存します。例えば、これについての別の修正は '$ scope.datepickerOptions = {enableTime:true}'を初期化することです。それ以上の情報や例がなければ、私はそれを正しく答えることはできません。 – Hoyen

0

それは私がしなければ

$timeout(function(){ 
 
    console.log(scope.enableTime) 
 
}, 600) 
 

 
//and in parent directive 
 

 
$timeout(function(){ 
 
    scope.datepickerOptions.enableTime = true //or whatever 
 
}, 500)

すべてFと思われますすべての場所に。しかし、それは私には清潔な解決策のようには見えません。結局のところ、私はこれまでにこのようなことに遭遇したことはありませんでした。そして、ディレクティブがロードされ、レンダリングされるとき、どのように誰が確実にできるのですか?

+0

JavaScriptは同期して実行されることを理解する必要があります。 JavaScriptの仕組みを完全に理解していないというのが問題だと思います。 JavaScriptでタイムアウトがどのように機能するかを調査して理解したいと思うかもしれません。 – Hoyen

関連する問題