2016-05-31 31 views
1

組み込みシステムのUIにAngularを使用しています。私はあなたがデスクトップブラウザ(組み込みシステムのシミュレーション)でUIを実行できるように、アプリケーションの設定を持っています。私は組み込みシステムのすべてのAPI関数を含むサービス層を持っています。そこで、シミュレーションのために、API関数をシミュレートするためにサービスレイヤーをスワップアウトします。これはうまくいきますが、今私の問題は、組み込みシステムの一部ではないシミュレーションで実際に行う必要があることです。別のコントローラからAngular Scope変数を設定する方法

いずれのコントローラでもシミュレーションのコードは必要ありません。単一の.jsファイルを読み込んで別のコントローラで関数を呼び出すだけで、シミュレーション用のコントローラを正常に取得できましたが、スコープ変数の値を変更することはできません。私はそれが期待されるように動作しません。

ここには何が起こるかを示すデモがあります。私は、第1のコントローラで第2のコントローラから関数を呼び出し、パラメータを渡しています。コンソールは正しい値を出力しますが、スコープ変数は変更されません。

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

 
.controller('Ctrl_1', function($scope) 
 
{ 
 
    $scope.myFunction = function(myParam) 
 
    { 
 
    console.log('Ctrl_1: ' + myParam); 
 

 
    // Demonstrates that the function is called, and with the correct value for myParam. 
 
    $('.console').append('<li>' + myParam + '</li>'); 
 

 
    $scope.myVar = myParam; 
 
    } 
 

 
    $scope.myFunction('Foo'); 
 
}); 
 

 
// sim.js 
 
$('.app-wrapper').attr('ng-controller', 'Ctrl_2'); 
 

 
app.controller('Ctrl_2', function($scope, $controller, $timeout) 
 
{ 
 
    var Ctrl_1_ViewModel = $scope.$new(); 
 

 
    $controller('Ctrl_1', { $scope: Ctrl_1_ViewModel }); 
 

 
    //$timeout(function() { Ctrl_1_ViewModel.myFunction('Bar') }); 
 

 
    $scope.testFunction = function() 
 
    { 
 
    Ctrl_1_ViewModel.myFunction('Bar'); 
 

 
    console.log('Ctrl_2: ' + Ctrl_1_ViewModel.myVar); 
 
    } 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div ng-app="myApp" class="app-wrapper"> 
 
    <div ng-controller="Ctrl_1"> 
 
    <h3>myVar = '{{ myVar }}'</h3> 
 
    <button ng-click="testFunction()">Set myVar equal to 'Bar'</button> 
 
    </div> 
 
    <ul class="console" style="list-style-type: none; padding: 0;"></ul> 
 
</div>

私もJSFiddle of the demoを持っています。

これを動作させるにはどうすればよいですか?あるいは、私が検討すべき別のアプローチがありますか?

+0

あなたは、ソリューションを提供するための –

答えて

1

全体のアプローチはまったく間違っています。 ngControllerを手作業で変更したことを角度がどのように知っていると思いますか?あなたはこの変更についての角ノウハウをできるようにh3要素を再コンパイルする必要があります。

$compile($document.find('h3'))(Ctrl_1_ViewModel); 

作業例:https://jsfiddle.net/cL96m2zx/5/

とサイドノートには - あなたはAngularjsを使用しているときにからDOMを操作することはできませんコントローラーを使用するには、DOM操作を停止し、代わりにangleディレクティブを使用する必要があります(または独自のカスタムディレクティブを作成し、そこからDOMを操作する必要がありますが、最後の手段として)。

+0

おかげできるだけ '$ rootScope'を使用する必要があります!なぜアプローチが完全に間違っていると言いますか?よりよいアプローチは何でしょうか?組み込みシステムのコードを変更せずに、私が必要とするものをどのように達成することができますか?DOM操作として '$( '。console')。append'を参照しているなら、当然のことながら、私はそれを決して生産ではしません。これはデモンストレーション目的のためのものです。もう一度、あなたのソリューションに感謝します!より良いアプローチを提供できれば素晴らしいだろう!ありがとう! – JDavis

+0

ああ、もしあなたがこれについて知っていれば、あなたは完全にうまい。私はあなたがangJSを使ってDOMを操作するためにまだjQueryを使用しているそれらの初心者の1人だと思いました。 –

+0

OK、これは私が与えたデモの解決策です。あなたが想像することができるように、私のアプリはこれほど単純ではなく、問題を再現するのに十分なものを提供したかっただけです。したがって、実際のアプリケーションでは、変数はng-repeatで使用される配列であり、この解決策は機能していないようです。私はフィドルを更新しました。 https://jsfiddle.net/whatisthebigpicture/cL96m2zx/6/ – JDavis

0

データを管理するファクトリを作成し、watchを使用して2番目のコントローラを更新することができます。

また、イベントでも可能です。 docsをご覧ください。 $broadcastまたは$emitは、イベントの方向によって必要なものです。 $rootScope.$broadcast('custom:eventName', {data: 'Bar'})のようなものを使用して、子スコープ内のリスナーに通知してください。$scope.$on('custom:eventName', function(evt, data) { ... }

変更についてアプリの多くの部分に通知したい場合は、イベントを使用します。変更を監視するコントローラーが2つまたは3つしかない場合は、データの監視で問題ありません。

以下のデモまたはfiddleをご覧ください。

var app = angular.module('myApp', []) 
 
.factory('sharedData', SharedDataService) 
 
.controller('Ctrl_1', function($scope , sharedData) 
 
{ 
 
\t $scope.$watch(function() { 
 
    \t return sharedData.getVar('myVar'); 
 
    }, function(newVal) { 
 
    \t $scope.myFunction(newVal); 
 
    }) 
 
\t 
 
    $scope.myFunction = function(myParam) { 
 
     console.log('Ctrl_1: ' + myParam); 
 

 
     // Demonstrates that the function is called, and with the correct value for myParam. 
 
     $('.console').append('<li>' + myParam + '</li>'); 
 

 
     $scope.myVar = myParam; 
 
     } 
 
    
 
    //$scope.myFunction('Foo'); 
 
}); 
 

 
// sim.js 
 
$('.app-wrapper').attr('ng-controller', 'Ctrl_2'); 
 

 
app.controller('Ctrl_2', function($scope, $controller, $timeout, sharedData) 
 
{ 
 
\t //var Ctrl_1_ViewModel = $scope.$new(); 
 
    
 
    //$controller('Ctrl_1', { $scope: Ctrl_1_ViewModel }); 
 
    
 
    //$timeout(function() { Ctrl_1_ViewModel.myFunction('Bar') }); 
 
    
 
    $scope.testFunction = function() 
 
    { 
 
    \t //Ctrl_1_ViewModel.myFunction('Bar'); 
 
    sharedData.setVar('myVar', 'Bar'); 
 
    //console.log('Ctrl_2: ' + Ctrl_1_ViewModel.myVar); 
 
    } 
 
}); 
 

 
function SharedDataService() { 
 
\t var _privateData = { 
 
    \t myVar: 'Foo' 
 
    }; 
 
    
 
\t var factory = { 
 
    \t setVar: function(name, newVal) { 
 
     \t _privateData[name] = newVal; 
 
     }, 
 
     getVar: function(name) { 
 
     \t return _privateData[name] 
 
     } 
 
    }; 
 
    
 
    return factory; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="myApp" class="app-wrapper"> 
 
    <div ng-controller="Ctrl_1"> 
 
    <h3>myVar = '{{ myVar }}'</h3> 
 
    <button ng-click="testFunction()">Set myVar equal to 'Bar'</button> 
 
    </div> 
 
    <ul class="console" style="list-style-type: none; padding: 0;"></ul> 
 
</div>

関連する問題