0

我正在使用带有 Breeze 和 Angular 的 MVC 4。

我已经创建了一些域模型,我只想显示一个模型列表。这是我的代码:

接口控制器:

[BreezeController]
public class TournamentApiController : ApiController
{
    private EFContextProvider<TournamentContext> _contextProvider;

    public TournamentApiController()
    {
        _contextProvider = new EFContextProvider<TournamentContext>();
    }

    [HttpGet]
    public string Metadata()
    {
        return _contextProvider.Metadata();
    }

    [HttpGet]
    public IQueryable<Tournament> Tournaments()
    {
        return _contextProvider.Context.Tournaments;
    }

    // ~/breeze/todos/SaveChanges
    [HttpPost]
    public SaveResult SaveChanges(JObject saveBundle)
    {
        return _contextProvider.SaveChanges(saveBundle);
    }
}

数据服务.js:

/* dataservice: data access and model management layer */
app.dataservice = (function (breeze) {

    breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);

    var serviceName = '/breeze/TournamentApi'; // route to the same origin Web Api controller

    // *** Cross origin service example  ***
    //var serviceName = 'http://todo.breezejs.com/breeze/todos'; // controller in different origin

    var manager = new breeze.EntityManager(serviceName);
    // manager.enableSaveQueuing(true);

    var dataservice = {
        getAllTournaments: getAllTournaments,
        createTournament: createTournament,
        saveChanges: saveChanges,
    };
    return dataservice;

    /*** implementation details ***/
    function getAllTournaments() {
        var query = breeze.EntityQuery
                .from("Tournaments");

        return manager.executeQuery(query).then(getAllSucceeded);
    }

    function getAllSucceeded(data) {
        debugger;
        return data.results;
    }

    function createTournament(name) {
        return manager.createEntity('Tournament', { Name: name });
    }

    function saveChanges() {
        return manager.saveChanges().fail(fail);
    }

    function fail(error) {
        console.log = error;
        debugger;
    }
})(breeze);

和我的角度控制器:

$scope.getAllTournaments = function () {
    dataservice.getAllTournaments().then(getAllSucceeded);
}

function getAllSucceeded(data) {
    debugger;
    if (data.length > 0)
        $scope.tournaments = data;
    else
        $scope.tournaments = [];
}

$scope.getAllTournaments();

在客户端,我可以看到存储在数据库中的 4 个对象。但是,该列表包含如下对象:

0: e.dataType
1: e.dataType
2: e.dataType
3: e.dataType

当我展开这样一个对象时,我看到:

_backingStore: Object
entityAspect: o
__proto__: Object1

当我进一步扩展 _backingStore 时,我看到了:

Date: Mon Jan 01 1900 00:00:00 GMT+0100 (W. Europe Standard Time)
Id: 1
Name: "123"

这当然是我需要的东西。

我感觉自己做错了什么,因为我认为e.dataType._backingStore在迭代列表时不应该在客户端代码中使用。

我该怎么做才能调用属性名称而不是整个路径?

4

1 回答 1

2

您没有说您的 Angular 应用程序失败,也没有说绑定失败,也没有说您在编写aTournament.name. 这一切都有效,是吗?

它没有,请告诉我们。

我认为您寻求的是对在调试器中检查实体时看到的值的解释。

首先,不,您不应该_backingstore直接引用 ... ever。名称中的“_”告诉您它是禁区。

在我解释发生了什么之前,我必须问你关于e.dataType._backingStore. 我从未见过e;没见过e.dataType。我无法在我正在使用的 4 个调试器(Chrome、IE10、FF、Visual Studio 2012)中的任何一个中重现它。请告诉我们您正在调试哪个浏览器。我感觉答案就在那儿。

但回到故事...

确实,这些实体在调试器中看起来确实有点奇怪。它们都或多或少地显示一个属性列表,如下所示:

_backingStore:对象
实体方面:ctor
__proto__: 对象

您的实体属性显然已经消失了。他们去哪儿了?这怎么可能起作用?然而它确实如此!显然您已经尝试过我们的 Angular 示例应用程序。他们工作对了吗?例如,他们展示了 Todo 描述。

是的,您会在深入研究时找到它们_backingStore。但 Angular 并没有这样做。你也不应该

谜团的答案是这些 Breeze 实体是使用 ECMA Script 5“定义的属性”构建的。您的实体属性被实现为具有内部具有 Breeze 逻辑的 getter 和 setter 的已定义属性。

出于某种原因,调试器不会列出已定义的属性,即使它们存在。虽然您不会aTournament.name在列表中看到该属性,但您可以阅读并设置它就好了。这就是 Angular 正在做的事情。你也应该这样。

FireBug 调试器(用于 FireFox)比大多数显示定义的属性做得更好。在这个快照中,我选择了第一个实体并输入了一个句点;FireBug 揭示了我的选择,其中包括实体属性(例如,Id、Description、...)。

FireBug 中的 Breeze/Angular 实体

要记住的是,您的实体属性确实存在,并且您可以以预期的方式使用它们进行编码。不要让调试器欺骗你。

如果您使用的是较旧的浏览器(例如,IE8),这些都不成立。较旧的浏览器不支持已定义的属性,Angular+Breeze 将无法使用它们。如果这些浏览器对您来说真的很重要并且您想使用 Breeze,请考虑使用替代模型库,例如 Knockout(参见HotTowel以获取与 Angular+Breeze 相当的完整堆栈)。

于 2013-05-28T06:02:16.770 回答