我可以将CollaborativeString放入自定义类型中吗?

Can I put a CollaborativeString inside a custom type?

本文关键字:类型 自定义 CollaborativeString 我可以      更新时间:2023-09-26

我正在阅读关于构建协作数据模型的Google Drive Realtime API文档。

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

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

如何令人沮丧。所以我想我得想办法了。我看到了一些选项:

  1. 忽略光标在协作过程中混乱的事实
  2. 使用collaborativeemap代替自定义类型,并在运行时用我的自定义类型包装它

可能会选择选项2

我想你误解了这个网站的运作方式,你的责任不是让别人告诉你怎么做,而是让别人从他们的一天中抽出时间来帮助你。

话虽如此,快速查看一下您所链接的页面会发现,您想要做的事情不仅是可能的,而且非常简单,并且与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中玩得开心——玩起来很有趣。

我知道这个问题和答案已经过时了,但为了参考起见,只是Grant Watters非常好的答案的最后一部分,ondoloadaded例程,相当误导。这个函数更适合于gapi.drive.realtime.load调用的第三个参数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...