【问题标题】:Functional object basics. How to go beyond simple containers?功能对象基础。如何超越简单的容器?
【发布时间】:2011-05-13 01:58:32
【问题描述】:

上,我有点聪明,在下边,我被 ADD 搞砸了。如果我有一个简单的例子,它符合我已经理解的,我明白了。我希望这里有人可以帮助我获得它。

我有一个页面,它会定期轮询服务器、处理数据、将其存储在一个对象中,然后将其显示在一个 div 中。它使用全局变量,并输出到我的 html 中定义的 div。我必须将它放入一个对象中,这样我才能创建多个实例,指向不同的服务器,并分别管理它们的数据。

我的代码基本上是这样的结构...

HTML...

<div id="server_output" class="data_div"></div>

JavaScript...

// globals
var server_url = "http://some.net/address?client=Some+Client";
var data = new Object();
var since_record_id;
var interval_id;

// window onload
window.onload(){

  getRecent();

  interval_id = setInterval(function(){
    pollForNew();
  }, 300000);
}

function getRecent(){
  var url = server_url + '&recent=20';
  // do stuff that relies on globals
  // and literal reference to "server_output" div.
}

function pollForNew(){
  var url = server_url + '&since_record_id=' + since_record_id;
  // again dealing with globals and "server_output".
}

我将如何将其格式化为一个将全局变量定义为属性和成员函数的对象(?)最好是在创建时构建自己的输出 div,并返回对它的引用。所以我可以做类似...

dataOne = new MyDataDiv('http://address/?client');
dataOne.style.left = "30px";

dataTwo = new MyDataDiv('http://different/?client');
dataTwo.style.left = "500px";

我的代码实际上比这更复杂,但我想如果我能理解这一点,我可以将它应用到我已经拥有的东西上。如果有什么我要求的,那是不可能的,请告诉我。我打算弄清楚这一点,并且会的。只需输入问题就可以帮助我 ADD 迷糊的头脑更好地处理我实际尝试做的事情。

一如既往...任何帮助都是帮助。

谢谢

跳过

更新: 这个我已经有了...

$("body").prepend("<div>text</div>");
this.test = document.body.firstChild;
this.test.style.backgroundColor = "blue";

那是在代码中创建的一个div,一个可以返回的引用。把它放在一个函数中,它可以工作。

再次更新: 我已经创建了可拖动的弹出窗口并将其作为具有一个原型功能的对象进行操作。这是fiddle。那是我的第一个小提琴!弹出窗口是我项目的关键,据我所知,数据功能将变得很容易。

【问题讨论】:

    标签: javascript function object syntax attributes


    【解决方案1】:

    这很接近:

    // globals
    var pairs = {
        { div : 'div1', url : 'http://some.net/address?client=Some+Client' } ,
        { div : 'div2', url : 'http://some.net/otheraddress?client=Some+Client' } ,
    };
    
    var since_record_id; //?? not sure what this is
    var intervals = [];
    
    // window onload
    window.onload(){  // I don't think this is gonna work
    
        for(var i; i<pairs.length; i++) {
            getRecent(pairs[i]);
            intervals.push(setInterval(function(){
                pollForNew(map[i]);
            }, 300000));
        }
    }
    
    function getRecent(map){
        var url = map.url + '&recent=20';
        // do stuff here to retrieve the resource
        var content = loadResoucrce(url);  // must define this
        var elt = document.getElementById(map.div);
        elt.innerHTML = content;
    }
    
    function pollForNew(map){
        var url = map.url + '&since_record_id=' + since_record_id;
        var content = loadResoucrce(url); // returns an html fragment
        var elt = document.getElementById(map.div);
        elt.innerHTML = content;
    }
    

    而 html 显然需要两个 div:

    <div id='div1' class='data_div'></div>
    <div id='div2' class='data_div'></div>
    

    您的“window.onload” - 我认为这行不通,但也许您已正确设置它并且不想费心放入所有代码。

    关于我建议的代码 - 它在全局范围内定义了一个数组,一个对象数组。每个对象都是一张地图,如果你喜欢的话,是一本字典。这些是每个 div 的参数。它提供 div id 和 url 存根。如果您有其他根据 div 变化的参数,请将它们放在地图中。

    然后,为每个地图对象调用一次getRecent()。在函数内部,您可以打开地图对象并获取其参数。

    您还希望使用相同的参数化设置循环内的间隔。我自己更喜欢使用 setTimeout(),但这只是我。

    您需要提供loadResource() 函数,该函数接受一个 URL(字符串)并返回该 URL 上可用的 HTML。


    这解决了模块化问题,但它不是解决问题的“对象”或基于类的方法。我不知道你为什么想要一个任务如此简单的人。这是一个可以做你想做的事情的对象:

    (function() {
    
        var getRecent = function(url, div){
            url = url + '&recent=20';
            // do stuff here to retrieve the resource
            var content = loadResoucrce(url);  // must define this
            var elt = document.getElementById(div);
            elt.innerHTML = content;
        }
    
        var pollForNew =  function(url, div){
            url = url + '&since_record_id=' + since_record_id;
            var content = loadResoucrce(url); // returns an html fragment
            var elt = document.getElementById(div);
            elt.innerHTML = content;
        }
    
        UpdatingDataDiv = function(map) {
            if (! (this instanceof arguments.callee) ) {
                var error = new Error("you must use new to instantiate this class");
                error.source = "UpdatingDataDiv";
                throw error;
            }
    
            this.url = map.url;
            this.div = map.div;
            this.interval = map.interval || 30000; // default 30s
            var self = this;
    
            getRecent(this.url, this.div);
    
            this.intervalId = setInterval(function(){
                pollForNew(self.url, self.div);
            }, this.interval);
        };
    
        UpdatingDataDiv.prototype.cancel = function() {
            if (this.intervalId) {
                clearInterval(this.intervalId);
                this.intervalId = null;
            }
        }
    
    })();
    
    var d1= new UpdatingDataDiv('div1','http://some.net/address?client=Some+Client');
    var d2= new UpdatingDataDiv('div2','http://some.net/otheraddress?client=Some+Client');
       ...
     d1.cancel();
    

    但您对d1d2 无能为力。您可以调用 cancel() 来停止更新。我想你可以添加更多功能来扩展它的功能。

    【讨论】:

    • 你说“我不知道你为什么想要一个任务如此简单的人。”这只是简单的示例,这些将​​是可拖动的弹出窗口,流式传输单独的 twitter 提要。他们将管理自己的拖动功能,并完全独立于其他页面活动。我实际上有一个相当棒的 twitter div。现在我想做的就是说“新”。就像我之前说的,如果我能理解简单,我就可以将其扩展到复杂。
    • 那应该可以了。 getRecent()pollForNew() 不会被公开调用,因此它们可以是私有的 var 函数。以这种方式定义,它们不能引用 this 来访问成员属性(如间隔或 div 等)。正如我为cancel() 展示的那样,您需要的任何其他公共成员函数都应该添加到原型中。这些可以参考this。在私有函数中定义所有内容,以保持全局命名空间干净。祝你好运。
    • 我看到你在定义对象内内联函数时的逻辑,这就是我要做的事情。 since_record_idpollForNew(); 使用。正如您从我发布的答案中看到的那样,我只是在寻找最简单的对象语法。我们都得从某个地方开始。 :) 感谢您的意见。
    【解决方案2】:

    好的,知道我需要什么了。这很简单。

    首先忽略window.onload,该对象被定义为一个函数,当您实例化一个新对象时,它会运行该函数。在函数中进行设置。

    其次,对于您希望对对象本地化的全局变量,只需在对象内将它们定义为this.variable_name;。这些变量在整个对象及其成员函数中都是可见的。

    第三,定义你的成员函数为object.prototype.function = function(){};

    第四,就我而言,对象函数应该return this; 这允许常规程序流程使用点符号检查对象的变量。

    这是我一直在寻找的答案。它采用我的非功能示例代码,并将其重新打包为一个对象...

    function ServerObject(url){
      // global to the object
      this.server_url = url;
      this.data = new Object();
      this.since_record_id;
      this.interval_id;
    
      // do the onload functions
      this.getRecent();
    
      this.interval_id = setInterval(function(){
        this.pollForNew();
      }, 300000);
    
      // do other stuff to setup the object
    
      return this;
    }
    
    // define the getRecent function
    ServerObject.prototype.getRecent = function(){
      // do getRecent(); stuff
      // reference object variables as this.variable;
    }
    
    // same for pollForNew();
    ServerObject.prototype.pollForNew = function(){  
      // do pollForNew(); stuff here.
      // reference object variables as this.variable;
    }
    

    然后在您的程序流程中,您执行类似...

    var server = new ServerObject("http://some.net/address");
    server.variable = newValue; // access object variables
    

    我在第一篇文章中提到了 ADD。我很聪明,知道物体有多么复杂,当我寻找例子和解释时,它们会暴露出那些让我思绪飘忽的复杂性的某些层面。很难深入了解让您从底层开始的简单规则。 “这个”的范围是什么?当然有一天我会弄明白的,但简单的事实是,你必须引用“this”。

    谢谢

    我希望我能提供更多。

    跳过

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-07
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 2023-04-04
      • 2012-09-04
      • 1970-01-01
      相关资源
      最近更新 更多