web-dev-qa-db-ja.com

AngularJsでの動的スコープ変数の設定-scope。<some_string>

routeParamまたはディレクティブ属性などから取得した文字列があり、これに基づいてスコープに変数を作成します。そう:

$scope.<the_string> = "something".

ただし、文字列に1つ以上のドットが含まれている場合、それを分割して、実際にスコープに「ドリルダウン」します。したがって、'foo.bar'$scope.foo.barになります。これは、単純なバージョンが機能しないことを意味します!

// This will not work as assigning variables like this will not "drill down"
// It will assign to a variables named the exact string, dots and all.
var the_string = 'life.meaning';
$scope[the_string] = 42;
console.log($scope.life.meaning);  // <-- Nope! This is undefined.
console.log($scope['life.meaning']);  // <-- It is in here instead!

文字列に基づいて変数を読み取る場合、$scope.$eval(the_string)を実行することでこの動作を取得できますが、値を割り当てるときにどのように行うのですか?

95
Erik Honn

私が見つけた解決策は、 $ parse を使用することです。

「Angular式を関数に変換します。」

誰かがより良いものを持っている場合は、質問に新しい答えを追加してください!

以下に例を示します。

var the_string = 'life.meaning';

// Get the model
var model = $parse(the_string);

// Assigns a value to it
model.assign($scope, 42);

// Apply it to the scope
// $scope.$apply(); <- According to comments, this is no longer needed

console.log($scope.life.meaning);  // logs 42
169
Erik Honn

エリックの答えを出発点として使用します。私にとってはもっと簡単な解決策を見つけました。

私のng-click機能には次のものがあります:

var the_string = 'lifeMeaning';
if ($scope[the_string] === undefined) {
   //Valid in my application for first usage
   $scope[the_string] = true;
} else {
   $scope[the_string] = !$scope[the_string];
}
//$scope.$apply

$ scope。$ applyの有無でテストしました。それなしで正常に動作します!

19
Andrew Gray

結果から動的angular変数を作成します

angular.forEach(results, function (value, key) {          
  if (key != null) {                       
    $parse(key).assign($scope, value);                                
  }          
});

追伸コントローラの関数に$ parse属性を渡すことを忘れないでください

13
Demodave

Lodashの使用に問題がなければ、_。set()を使用して1行で必要なことを実行できます。

_.set(object、path、value)オブジェクトのパスのプロパティ値を設定します。パスの一部が存在しない場合は作成されます。

https://lodash.com/docs#set

したがって、例は次のようになります:_.set($scope, the_string, something);

5
NorthernStar

すでに与えられた答えに追加するために、以下が私のために働いた:

HTML:

<div id="div{{$index+1}}" data-ng-show="val{{$index}}">

ここで、$indexはループインデックスです。

Javascript(valueは関数に渡されるパラメーターで、現在のループインデックスの$indexの値になります):

var variable = "val"+value;
if ($scope[variable] === undefined)
{
    $scope[variable] = true;
}else {
    $scope[variable] = !$scope[variable];
}
4
Riaz

覚えておいてください:これはJavaScriptにすぎず、Angular JSとは関係ありません。だから、魔法の「$」記号について混同しないでください;)

主な問題は、これが階層構造であることです。

console.log($scope.life.meaning);  // <-- Nope! This is undefined.
=> a.b.c

「$ scope.life」は存在しませんが、上記の用語は「意味」を解決したいため、これは未定義です。

解決策は

var the_string = 'lifeMeaning';
$scope[the_string] = 42;
console.log($scope.lifeMeaning);
console.log($scope['lifeMeaning']);

またはもう少しエフォードで。

var the_string_level_one = 'life';
var the_string_level_two = the_string_level_one + '.meaning';
$scope[the_string_level_two ] = 42;
console.log($scope.life.meaning);
console.log($scope['the_string_level_two ']);

構造オブジェクトにアクセスできるのは

var a = {};
a.b = "ab";
console.log(a.b === a['b']);

これに関するいくつかの優れたチュートリアルがあり、JavaScriptの楽しさをガイドします。

について何かがあります

$scope.$apply();
do...somthing...bla...bla

「angular $ apply」をウェブで検索すると、$ apply関数に関する情報が見つかります。そして、この方法を使用するのが賢明です(もし$ applyフェーズに慣れていない場合)。

$scope.$apply(function (){
    do...somthing...bla...bla
})
3
Raxa

以下のLodashライブラリを使用している場合は、angularスコープで動的変数を設定する方法です。

angularスコープに値を設定します。

_.set($scope, the_string, 'life.meaning')

angularスコープから値を取得します。

_.get($scope, 'life.meaning')
0
Sagar Vaghela