11

さらに詳しい情報が必要な場合や、何か明確にしたい場合はお知らせください。これを理解するためにさまざまなことを試しましたが、解決策が見つかりませんでした。

私は angularJS に比較的慣れていないので、いくつかのデータ層でアプリを構築しようとしています。コントローラ PageController の body のスコープにいくつかの基本的なユーザー情報が格納されています。次に、$routeParams (コントローラーの SettingsController を使用) を使用して読み込まれる設定フォームを作成します。このフォームには、テンプレート用のカスタム ディレクティブがいくつか含まれています。ディレクティブはネストされているため、トランスクルージョンを使用して最初のディレクティブの中に 2 番目のディレクティブをロードしています。これはすべて問題なく機能しているようです。

私の問題はuser.firstname、最も内側のディレクティブ内からフィールドを参照しようとしていて、双方向のデータバインディングを使用してテキストボックスに加えられた変更を許可し、PageController スコープの値も変更したいことです。この種の問題の多くは ng-model でプリミティブを使用することによって引き起こされることを知っていますが、プロトタイプの継承を無効にするために、すべてを追加のオブジェクト内に配置しようとしました。ここで何が間違っていますか?

これは私のコードのJSFiddleで、問題を切り分けるために可能な限り削除されています。この例では、PageController スコープに直接ある外側のテキスト ボックスを入力すると、そのテキスト ボックスが変更されるまで内側のテキスト ボックスが変更され、接続が切断されます。これは、他の質問で説明されているプリミティブの使用の問題とまったく同じように思えますが、ここで問題がどこにあるのかわかりません。

HTML:

<body class="event-listing" ng-app="app" ng-controller="PageController">
    <div class="listing-event-wrap">
        <input type="text" ng-model="user.firstname" />
        <div ng-controller="SettingsController">
            <section block title="{{data.updateInfo.title}}" description="{{data.updateInfo.description}}">
                <div formrow label="{{data.updateInfo.labels.firstname}}" type="textInput" value="user.firstname"></div>
            </section>
        </div>
    </div>
</body>

Angular ディレクティブ:

app.directive('formrow', function() {
return {
    scope: {
            label: "@label",
            type: "@type",
            value: "=value" 
    },
    replace: true,
    template: '<div class="form-row">' + 
            '<div class="form-label" data-ng-show="label">{{label}}</div>' + 
            '<div class="form-entry" ng-switch on="type">' + 
                '<input type="text" ng-model="value" data-ng-switch-when="textInput" />' + 
            '</div>' + 
        '</div>'
}
});
app.directive('block', function() {
return {
    scope: {
            title: "@title",
            description: "@description" 
    },
    transclude: true,
    replace: true,
    template: '<div class="page-block">' +
            '<h2 data-ng-show="title">{{title}}</h2>' + 
            '<p class="form-description" data-ng-show="description">{{description}}</p>' + 
            '<div class="block-inside" data-ng-transclude></div>' + 
            '</div>'
}
});

角度コントローラー:

app.controller("PageController", function($scope) {
    $scope.user = {
        firstname: "John"
    };
});
app.controller("SettingsController", function($scope) {
    $scope.data = {
        updateInfo: {
            title: "Update Your Information",
            description: "A description here",
            labels: {
                firstname: "First Name"
            }
        }
    }
});
4

3 に答える 3

8

ディレクティブのテキスト ボックスは、そのモデルのオブジェクトの代わりに (ng-model="value"ではなくng-model="someobj.somevalue") プリミティブを使用するため、そのモデルはローカル スコープでのみ作成され、親はそれにアクセスできません。

修正は、オブジェクト プロパティとしてドット ルールを使用してディレクティブ テキスト ボックス モデルを定義することです。

ng-model="value.firstname"

user次に、プリミティブ プロパティだけでなく、オブジェクト全体をディレクティブに渡します。

<div formrow ... value="user"></div>

ここにデモがあります

于 2013-06-19T02:47:52.990 に答える
0

ng-switchこの問題は、doc の理解スコープからの gitによって引き起こされます。

ng-switch スコープの継承は、ng-include と同じように機能します。したがって、親スコープのプリミティブに双方向のデータ バインディングが必要な場合は、$parent を使用するか、モデルをオブジェクトに変更してから、そのオブジェクトのプロパティにバインドします。これにより、親スコープ プロパティの子スコープの非表示/シャドーイングが回避されます。

したがって、テキストボックスにテキストを入力すると。以下のコードがng-switchスコープに対して実行されます。

$scope.value="the text you typed"

したがって、プロトタイプチェーンを参照して検索することはありません。これにより、スコープvalueの新しいプロパティが作成されます。ng-switch

それをどのように証言するのですか?

に変更valueした場合$parent.value。すべてがうまくいくでしょう。for プリミティブ型 ( dot がない場合ng-switch、angularjs は をプリミティブ型として認識します) はディレクティブ スコープを参照するためです。value$parentformrow

を削除するng-switchか、ドキュメントに記載されているとおりに実行してください。問題はなくなります。

.さらに重要なことに、ドキュメントでは、双方向バインディングを適用する場合、モデルを参照するために常にドットを使用することを推奨しています。

私が何か間違ったことを言ったら。親切に私を修正して、正しくしてください。ありがとう。

于 2014-07-17T07:29:55.713 に答える