2

私のプロジェクトでは AngularJS + Django Tasypie を使用しています。以下に投稿した CoffeeScript コードを使用して、フォームの送信を処理しています。Angular で開発を始めたばかりなので、改善点を教えてください。サービスや $resource の使用でしょうか。"Project" エンティティには oneToMany "Client" 関係があることに注意してください。

ありがとうございました。

汎用モデル クラス:

class window.Model
    constructor: (options) ->
        @$scope = options.$scope
        @$http = options.$http
        @id = if options.id? then options.id

    fetch: (cb= ->) =>
        @$http.get(@url + '/' + @id).success (data) =>
            @toScope(data)
            cb(data)

    fetchAll: (cb= ->) =>
        @$http.get(@url).success (data) =>
        @toScopeAll(data)
        cb(data)

    save: (data, cb= ->) ->
        @update data, cb if @id? else @create data, cb

    create: (cb= ->) ->
        @$http.post(@url + '/', @fromScope()).success cb

    update: (cb= ->) =>
        @$http.put(@url + '/' + @id, @fromScope()).success cb

    remove: (cb= ->) ->
        @$http.delete(@url + '/' + @id).success cb

プロジェクト/クライアント モデル クラス:

    class window.ProjectModel extends Model
        url: '/api/project'

        toScope: (data) =>
            @$scope.project = data
            @$scope.client = @$scope.project.client.id

        fromScope: (data) =>
            id: @$scope.project.id
            name: @$scope.project.name
            client: id: @$scope.client


    class window.ClientModel extends Model
        url: '/api/client'

        toScopeAll: (data) =>
        @$scope.clients = [id: '0', name: 'Choose...'].concat data.objects

コントローラーコード:

window.ProjectCtrl = ($scope, $routeParams, $http) ->

    redirect = -> window.location = '#/projects'
    $scope.save = -> project.save redirect
    $scope.delete = -> project.remove redirect
    $scope.cancel = redirect

    $scope.client = '0'
    client = new ClientModel($scope: $scope, $http: $http)
    client.fetchAll()

    project = new ProjectModel($scope: $scope, $http: $http)

    if $routeParams.projectId?
        $scope.formType = 'update'
        project.id = $routeParams.projectId
        project.fetch()
4

1 に答える 1

0

データ エンティティごとに 1 つのルートにこだわっているように感じます。これはおそらく、シリアライゼーション レイヤーをデータ モデルに結合していることが原因です。ここでアプローチを再考することをお勧めします。これは、やる気のない継承のように感じます。

モデルをシンプルでロジックのない JavaScript オブジェクトに保つ​​ようにしてください。次に、すべてのデータ構造に対して機能する単一のシリアライゼーション/永続化レイヤーを使用する必要があります。継承を避けてみてください。ここでは役に立ちません。経験則として、私は継承よりも構成を好みます。

最後に、一括取引を行う必要があるようです。永続レイヤーが分離されたので、永続レイヤーを変更して一度に複数の JavaScript オブジェクトを更新できます。次に、サーバー上にトランザクション ルートを作成し、次のようなデータ構造を受け入れることができます。

[
  ['create', 'project', {project_name: ...}]
  ['create', 'client', {client_attrs}]
]

追加のボーナスとして、1 回の呼び出しでトランザクション全体を処理できるため、操作の 1 つがビジネス ロジックに失敗した場合に、サーバーでロールバックを処理できます。

アップデート

クライアントをプロジェクト ID に関連付ける必要があることに気付きました。クライアントで ID を生成できる場合 (UUID を使用しますか?)、このアプローチはそのまま機能します。

それ以外の場合は、次のように、クライアントが埋め込まれたプロジェクトのデータ構造を送信する「ネストされた属性」ルート全体をたどることができます。

{
  project_name: "...",
  clients: [{client1_attrs}, ...]
}

このアプローチはよく使われますが、私の経験ではうまくいくことはめったにないので、私は好きではありません。(削除をどのように処理しますか?すべての属性を指定し、関連するすべてのクライアントを毎回更新する必要がありますか?クライアントが複数のプロジェクトに関連付けられている場合はどうなりますか?クライアントがどれほど迅速に崩壊するかがわかります。)

UUIDが可能ではないことを考えると、私が好むアプローチは、トランザクションサーバーコントローラーに、以前の手順で返された値を設定できるようにすることだと思います。

このデータ構造は、トランザクション リストの 0 番目の位置でシリアル化されたデータ エンティティのフィールド「id」を検索し、シリアル化の前にこのクライアントの project_id として設定するようトランザクション コントローラに指示します。

[
  ['create', 'project', {project_name: ...}]
  ['create', 'client', {client_attrs}, {project_id: [0, 'id']}]
]
于 2012-11-06T20:02:59.463 に答える