我可以在自定义类型中放置CollaborativeString吗?

时间:2014-06-26 03:36:43

标签: javascript google-drive-realtime-api

我正在Building a Collaborative Data Model上阅读Google Drive Realtime API文档。

我非常喜欢gapi.drive.realtime.databinding.bindString行为的方式。当多个人在同一文本框中键入时,它不会弄乱您的光标位置。但它要求你传递一个CollaborativeString。

但是,如果您注册自定义类型,则无论您定义的是哪种类型的字段,都必须使用gapi.drive.realtime.custom.collaborativeField,并且无法将其中一种传递给bindString。事实上,collabField类型似乎没有在任何地方记录,并且在控制台中检查它表明它没有方法。这意味着没有registerReference方法,CollaborativeString用它来跟踪光标位置。

多么令人沮丧。所以我想我必须解决它。我看到了几个选项:

  1. 忽略光标在协作期间搞砸的事实
  2. 使用CollaborativeMap而不是自定义类型,并在运行时使用我的自定义类型将其包装
  3. 可能会做选项2。

2 个答案:

答案 0 :(得分:0)

我认为你误解了这个网站是如何运作的,其他人没有责任向你展示如何做某事 - 你要求别人花时间来帮助你。

话虽如此,快速查看您链接的页面会显示您想要做的事情不仅可行,而且非常简单并且与bindString兼容。从该页面的示例代码中窃取:

// Call this function before calling gapi.drive.realtime.load
function registerCustomTypes()
{
    var Book = function () { };

    function initializeBook()
    {
        var model = gapi.drive.realtime.custom.getModel(this);

        this.reviews = model.createList();
        this.content = model.createString();
    }

    gapi.drive.realtime.custom.registerType(Book, 'Book');

    Book.prototype.title = gapi.drive.realtime.custom.collaborativeField('title');
    Book.prototype.author = gapi.drive.realtime.custom.collaborativeField('author');
    Book.prototype.isbn = gapi.drive.realtime.custom.collaborativeField('isbn');
    Book.prototype.isCheckedOut = gapi.drive.realtime.custom.collaborativeField('isCheckedOut');
    Book.prototype.reviews = gapi.drive.realtime.custom.collaborativeField('reviews');
    Book.prototype.content = gapi.drive.realtime.custom.collaborativeField('content');

    gapi.drive.realtime.custom.setInitializer(Book, initializeBook);
}

// Pass this as the 2nd param to your gapi.drive.realtime.load call
function onDocLoaded(doc)
{
    var docModel = doc.getModel();
    var docRoot = docModel.getRoot();

    setTimeout(function ()
    {
        var book = docModel.create('Book');

        book.title = 'Moby Dick';
        book.author = 'Melville, Herman';
        book.isbn = '978-1470178192';
        book.isCheckedOut = false;

        book.content.setText("Call me Ishmael. Some years ago - never mind how long precisely - having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.");

        docRoot.set('tbook', book);

        debugger;
    }, 0);
}

祝你好运并享受Realtime API的乐趣 - 玩起来很有趣。

答案 1 :(得分:0)

我知道这个问题和答案正在变老,但为了参考,只有Grant Watters的最后一部分'非常好的答案,onDocLoaded例程,相当误导。写入的函数更适合于gapi.drive.realtime.load调用的第3个参数,onInitializeModel回调。

每次加载Doc时都会调用第二个参数。您通常不会像上述例程一样反复添加相同的对象......相反,您通常会设置事件处理,数据绑定等。此版本可能会有所阐述:

// Pass this as the 2nd param to your gapi.drive.realtime.load call
function onDocLoaded(doc)
{
    var docModel = doc.getModel();
    var docRoot = docModel.getRoot();
    var text = doc.getModel().getRoot().get("text");

    // Add an event listener...
    text.addEventListener(gapi.drive.realtime.EventType.TEXT_INSERTED, onStringChanged);

    // ...and/or bind to collaborative objects:
    var textArea = document.getElementById('textArea1')
    textBinding = gapi.drive.realtime.databinding.bindString(text, textArea);

    etc...
}

不是偶然的,bindString返回绑定对象,这需要"取消绑定"稍后,在加载下一个Doc时阻止AlreadyBound错误或其他意外行为。做这样的事情:

function onDocLoaded(doc)
{
    // Clear any previous bindings etc:
    if (textBinding) { textBinding.unbind() };
    textBinding = null;

    etc...