如何正确设置一个商店作为您的网络应用程序中的单个指针

2024-02-29

我有一家本土商店,有一个简单的身份映射。当我从中返回模型数组并将其绑定到控制器“模型”时,它反映了您的期望

当您第一次点击路线时,它会在模板中反映为 你会期望

但稍后,如果我获得相同的商店实例(它是单例)并将对象推送到 IdentityMap 中,它不会自动更新以前的模板

商店本身是超级基本的(没有关系/只是推送对象并通过 id 获取)

function buildRecord(type, data, store) {
    var containerKey = 'model:' + type;
    var factory = store.container.lookupFactory(containerKey);

    var record = factory.create(data);

    var id = data.id;
    identityMapForType(type, store)[id] = record;

    return record;
}

function identityMapForType(type, store) {
    var typeIdentityMap = store.get('identityMap');

    var idIdentityMap = typeIdentityMap[type] || {};
    typeIdentityMap[type] = idIdentityMap;

    return idIdentityMap;
}

var Store = Ember.Object.extend({
    init: function() {
        this.set('identityMap', {});
    },

    push: function(type, data) {
        var record = this.getById(type, data.id);
        if (record) {
            record.setProperties(data);
        } else {
            record = buildRecord(type, data, this);
        }
        return record;
    },

    getById: function(type, id) {
        var identityMap = identityMapForType(type, this);
        return identityMap[id] || null;
    }

    getEverything: function(type) {
        var identityMap = identityMapForType(type, this);
        var keys = Object.keys(identityMap);
        var values = [];
        for (var i = 0; i < keys.length; i++)
        {
            var val = identityMap[keys[i]];
            values.push(val);
        }
        return values;
    }
});

Ember.onLoad('Ember.Application', function(Application) {
    Application.initializer({
        name: "store",
        initialize: function(container, application) {
            application.register('store:main', Store);
            application.inject('controller', 'store', 'store:main');
            application.inject('route', 'store', 'store:main');
        }
    });
});

在我的模型挂钩中(比如说在查找所有路线中),我只需查询每个项目并将它们推送到商店中

//inside my model find method lets say ...
find: function(store) {
    var url = "/api/foo";
    $.getJSON(url, function(response) {
        response.forEach(function(data) {
            var model = store.push("foo", data);
        }
    }
    return store.getEverything("foo");
}

所以我假设我的控制器的模型是这个绑定数组(对这个模型数组使用内存中的单个指针)

然而,当我在控制器提交操作中执行此操作时,它不会重新渲染上一个视图(以显示添加到该商店数组中的新项目)

actions: {
    submit: function() {
        var foo = {}; // assume this is a real json response or js object
        var store = this.get("store");
        store.push("foo", foo);
    }
}

因此,今天我被迫获取父控制器并将这个新对象“设置”/“推送”到它的内容/模型属性:(

有人知道我在这里做错了什么吗?


我喜欢本土解决方案,它们通常更容易使用并融合您正在处理的内容。

所以我真的很惊讶这部分的工作:

//inside my model find method lets say ...
find: function(store) {
    var url = "/api/foo";
    $.getJSON(url, function(response) {
        response.forEach(function(data) {
            var model = store.push("foo", data);
        }
    }
    return store.getEverything("foo");
}

如果我通读它,我会看到你进行了 ajax 调用,然后返回store.getEverything紧接着(不保证 ajax 调用已完成)。然后里面getEverything您创建一个名为的新数组values然后迭代连接所有当前可用记录的恒等映射并返回。此时,您的商店不知道该阵列正在发生。因此,对商店的任何更改都不会被推送到数组中,它们可能会将其放入身份映射中,但它不会提供给 getEverything 数组。

有几种解决方案,其中一种是跟踪您的所有数组。该集合的构建成本非常低,搜索成本更高,因此保留身份映射也将非常有益。您可以遵循相同的模式,但一个集合将是地图,而另一个集合将是所有内容的数组。

修改的构建记录

function buildRecord(type, data, store) {
    var containerKey = 'model:' + type;
    var factory = store.container.lookupFactory(containerKey);

    var record = factory.create(data);

    var id = data.id;
    identityMapForType(type, store)[id] = record;
    everythingArrayForType(type, this).pushObject(record);
    return record;
}

复制粘贴,可能可以重构

function everythingArrayForType(type, store) {
    var everythingArrays = store.get('everythingArrays');
    var arr = everythingArrays[type] || [];
    everythingArrays[type] = arr;

    return arr;
}

稍微修改了商店

var Store = Ember.Object.extend({
    init: function() {
        this.set('identityMap', {});
        this.set('everythingArrays', {});
    },
    push: function(type, data) {
        var record = this.getById(type, data.id);
        if (record) {
            record.setProperties(data);
        } else {
            record = buildRecord(type, data, this);
        }
        return record;
    },

    getById: function(type, id) {
        var identityMap = identityMapForType(type, this);
        return identityMap[id] || null;
    }

    getEverything: function(type) {
        return everythingArrayForType(type, this);
    }
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何正确设置一个商店作为您的网络应用程序中的单个指针 的相关文章

随机推荐