如何使用BreezeJS检索数据?

时间:2013-05-26 14:59:15

标签: javascript asp.net-mvc-4 angularjs breeze

我正在使用MVC 4和Breeze和Angular。

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

ApiController:

[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);
    }
}

DataService.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();

在客户端,我可以看到存储在DB中的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

如果只调用属性名称而不是整个路径,我该怎么办?

1 个答案:

答案 0 :(得分:2)

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

它没有,请告诉我们。

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

首先,不,您不应该直接引用_backingstore ......永远。名称中的“_”告诉您它不受限制。

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

但回到故事......

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

_backingStore: Object
entityAspect: ctor
__proto__: Object

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

是的,当您钻取_backingStore时,您会找到它们。但是Angular没有这样做。你也不应该

这个谜团的答案是这些Breeze实体是用ECMA Script 5“defined properties”构建的。您的实体属性实现为定义的属性,其中包含具有Breeze逻辑的getter和setter。

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

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

Breeze/Angular entity in FireBug

要记住的是,您的实体属性确实在那里,您可以按预期的方式使用它们进行编码。不要让调试人员欺骗你。

如果您使用较旧的浏览器(例如,IE8),这一切都不成立。较旧的浏览器不支持定义的属性,Angular + Breeze不支持它们。如果这些浏览器对您非常重要并且您想使用Breeze,请考虑使用替代模型库,例如Knockout(请参阅HotTowel以获得与Angular + Breeze相当的完整堆栈)。