问:
Login to webpage using Java client
I need to programmatically login to a website using a Java client. The website does not have any API and uses a form authentication. After login in my client will need to download a file from the same website that is under a different URL.

I've tried basic authentication for the second URL but that did not work. I also tried implementing a client similar to this example: http://www.mkyong.com/java/how-to-automate-login-a-website-java-example/ .                                   It does not seem to obtain the session for my client to use for the file download URL.

Here is the source code of what i am trying to achieve:

```<code>import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;

public class Client {

    public static void main(String [] args) throws Exception {
        String authURL = "https://hostname/webapp/loginUrl?parameters=values";
        String fileURL = "https://hostname/webapp/downloadFile?parameters=values";
        String username = "username";
        String password = "password";

        // downloading the login page
        List<String> cookies = null;
        CookieHandler.setDefault(new CookieManager());
        URL url = new URL(authURL);
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setUseCaches(false);
        conn.setRequestProperty("User-Agent", "Mozilla/5.0");
        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        cookies = conn.getHeaderFields().get("Set-Cookie");
        String loginPage = response.toString();

        // extracting form parameters
        Document doc = Jsoup.parse(loginPage, "", Parser.xmlParser());
        Element loginform = doc.getElementById("Logon");
        Elements inputElements = loginform.getElementsByTag("input");
        List<String> paramList = new ArrayList<String>();
        for(Element inputElement: inputElements) {
            String key = inputElement.attr("name");
            String value = inputElement.attr("value");
            if(key.equals("logonId")) {
                value = username;
            }

            if(key.equals("logonPassword")) {
                value = password;
            }
            paramList.add(key + "=" + URLEncoder.encode(value, "UTF-8"));
        }

        StringBuilder params = new StringBuilder();
        for(String param: paramList) {
            if(params.length() == 0) {
                params.append(param);
            } else {
                params.append("&" + param);
            }
        }

        // send post request to login
        conn = (HttpsURLConnection) url.openConnection();
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0");
        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        for(String cookie : cookies) {
            conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
        }
        conn.setRequestProperty("Connection", "keep-alive");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Content-Length", Integer.toString(params.length()));
        conn.setDoOutput(true);
        conn.setDoInput(true);

        DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
        wr.writeBytes(params.toString());
        wr.flush();
        wr.close();

        // download the file
        url = new URL(fileURL);
        conn = (HttpsURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setUseCaches(false);
        conn.setRequestProperty("User-Agent", "Mozilla/5.0");
        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        if(cookies != null) {
            for(String cookie: cookies) {
                conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
            }
        }

        in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        response = new StringBuffer();

        while((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        cookies = conn.getHeaderFields().get("Set-Cookie");

        // save the file to local disk
        BufferedWriter bwr = new BufferedWriter(new FileWriter(new File("c:/temp/content")));
        bwr.write(response.toString());
        bwr.flush();
        bwr.close();
    }
}
</code>```

What is the correct approach for this type of scenario? Should my client be capturing and maintaining a cookie/session/session token that the page creates?

Thanks.

答:
If you need a session or something similar depends on the website. Therefore you should first check what the web page really does.

My common approach is to use a web-proxy like Fiddler or Burp to investigate all network calls while browsing the page manually. Then I can redo certain interesting calls from within the proxy and remove step-by-step the headers to see what is really necessary.
If the request is striped down to the maximum and all required headers/data has been identified you can re-program the call in Java.

Using Apache commons http with cookie manager would be my preferred Java library for implementing this on Java side (but that depends on the needs of the web site).

If the web page is very very complex and obfuscated sometimes using a real browser is the simplest way. Depending on the web page you ca tools like ui4j or Selenium (using jBrowserDriver or Firefox as engine) to remote control a web-browser and simulate a surfing user.

Title: Login to webpage using Java client

Body:
I need to programmatically login to a website using a Java client. The website does not have any API and uses a form authentication. After login in my client will need to download a file from the same website that is under a different URL.

I've tried basic authentication for the second URL but that did not work. I also tried implementing a client similar to this example: http://www.mkyong.com/java/how-to-automate-login-a-website-java-example/ .                                   It does not seem to obtain the session for my client to use for the file download URL.

Here is the source code of what i am trying to achieve:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;

public class Client {

    public static void main(String [] args) throws Exception {
        String authURL = "https://hostname/webapp/loginUrl?parameters=values";
        String fileURL = "https://hostname/webapp/downloadFile?parameters=values";
        String username = "username";
        String password = "password";

        // downloading the login page
        List<String> cookies = null;
        CookieHandler.setDefault(new CookieManager());
        URL url = new URL(authURL);
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setUseCaches(false);
        conn.setRequestProperty("User-Agent", "Mozilla/5.0");
        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        cookies = conn.getHeaderFields().get("Set-Cookie");
        String loginPage = response.toString();

        // extracting form parameters
        Document doc = Jsoup.parse(loginPage, "", Parser.xmlParser());
        Element loginform = doc.getElementById("Logon");
        Elements inputElements = loginform.getElementsByTag("input");
        List<String> paramList = new ArrayList<String>();
        for(Element inputElement: inputElements) {
            String key = inputElement.attr("name");
            String value = inputElement.attr("value");
            if(key.equals("logonId")) {
                value = username;
            }

            if(key.equals("logonPassword")) {
                value = password;
            }
            paramList.add(key + "=" + URLEncoder.encode(value, "UTF-8"));
        }

        StringBuilder params = new StringBuilder();
        for(String param: paramList) {
            if(params.length() == 0) {
                params.append(param);
            } else {
                params.append("&" + param);
            }
        }

        // send post request to login
        conn = (HttpsURLConnection) url.openConnection();
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0");
        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        for(String cookie : cookies) {
            conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
        }
        conn.setRequestProperty("Connection", "keep-alive");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Content-Length", Integer.toString(params.length()));
        conn.setDoOutput(true);
        conn.setDoInput(true);

        DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
        wr.writeBytes(params.toString());
        wr.flush();
        wr.close();

        // download the file
        url = new URL(fileURL);
        conn = (HttpsURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setUseCaches(false);
        conn.setRequestProperty("User-Agent", "Mozilla/5.0");
        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        if(cookies != null) {
            for(String cookie: cookies) {
                conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
            }
        }

        in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        response = new StringBuffer();

        while((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        cookies = conn.getHeaderFields().get("Set-Cookie");

        // save the file to local disk
        BufferedWriter bwr = new BufferedWriter(new FileWriter(new File("c:/temp/content")));
        bwr.write(response.toString());
        bwr.flush();
        bwr.close();
    }
}

What is the correct approach for this type of scenario? Should my client be capturing and maintaining a cookie/session/session token that the page creates?

Thanks.


来源: stackexchange

问:
PHPMailer - forward email to group
I have a need for everyone in my organization to send emails to everyone else in the group.

As there are hundreds of members, and the membership changes often, it is not practical to use the traditional CPanel email forwarding method.  So I thought I would pipe the email to a php script, get all the members’ email addresses from the database (checking to make sure the original sender was also in the database) and send on the email to all members using PHPMailer.

I parsed the header in the PHP script to get the From, Subject (adding these of course to PHPMailer), Content-Type, and boundary.  Then I collected the actual email message in a variable $message including the lines that say (in this case)

```<code>“This is a multi-part message in MIME format.
--------------3D4FAACFC2C069EFCDAE6DC6, etc.  (This is of course in text format.)
</code>```

Just before the PHPMailer Send command, I included:

```<code>$mail -> IsHTML(false);
// (I also tried not including this command at all – no change)
$mail->Body =$message;
$mail->addCustomHeader("Content-Type", $content_type . "  boundary=" . $boundary);

 $content_type and $boundary are the variables I parsed from the original header
</code>```

As this is still in development, I sent the email to my address only.  It was received and displayed properly (both the plain and html as usual), but was marked as Spam – the received Header had the Subject already marked as Spam so I assume PHPMailer did it.

I noticed on the received Header that my custom header appeared correctly:

```<code> Content-Type: multipart/alternative;  boundary="------------3D4FAACFC2C069EFCDAE6DC6"
</code>```

The received header also had another Content-Type: text/plain; charset=iso-8859-1 after the above which I assume PHPMailer added.  Maybe the two Content-Types is what triggered the Spam tag.  I then tried adding $mail->header_remove ('Content-Type'); after the Body call and before addCustomHeader, but the additional  Content-Type: text/plain; charset=iso-8859-1 was still in the received header and it was still marked as Spam.

I am using PHPMailer version 5.2.22, and using

```<code>$mail->IsSMTP();
, $mail->SMTPAuth = true;
$mail->SMTPSecure = 'ssl';
</code>```

I can’t continue to unsuccessfully experiment forever as I am afraid sending lots of Spam emails will get me in trouble, so I am hoping someone can tell what I am doing wrong, or even if my overall strategy is flawed.   I wish also there was a way to get the header that PHPMailer is going to use before it actually sends out the mail.

Note: my organization is a charitable group with little money, so we can't afford paid SMTP's.  I've tried using the free versions of some on the market (not for the above project) but given you are using a shared IP with many others using the free service you often get emails kicked back because others sharing your IP have been Spam tagged

Thanks

答:
This is the entire header (I deleted some of the content just to keep this note a bit brief) that I received to my personal email (b...@....com) from my "forward email" script which uses everybody@....org as the originating address.  You can see the Content_Type I added to PHPMailer via $mail->addCustomHeader("Content-Type", $content_type . "  boundary=" . $boundary);(which is the multipart.. line) and the one PHPMailer itself added (text/plain...).  The email was received fine and displayed properly except for the Spam added to the Subject line:</p>

```<code>From - Sat Mar 25 12:51:13 2017
STUFF
Return-Path: <everybody@....org>
Received: from dnvrco-pub-iedge-vip.email.rr.com ([107.14.70.244])
          by dnvrco-fep06.email.rr.com
          (InterMail vM.8.04.03.24 201-2389-100-172-20151028) with ESMTP
          id <20170325165112.EUNA23395.dnvrco-fep06.email.rr.com@dnvrco-pub-iedge-vip.email.rr.com>
          for <bmadder@...>; Sat, 25 Mar 2017 16:51:12 +0000
Return-Path: <everybody@....org>
Received: from [173.205.126.142] ...
Received: from ecbiz194.inmotionhosting.com .....
Date: Sat, 25 Mar 2017 12:51:01 -0400
To: b...@....com
From: everybody@....org
Message-ID: ...
Content-Type: multipart/alternative;  boundary="------------3D4FAACFC2C069EFCDAE6DC6"
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
X-OutGoing-Spam-Status: No, score=-1.0
X-AntiAbuse:...
X-Get-Message-Sender-Via: ecbiz194.inmotionhosting.com: authenticated_id: everybody@....org
X-Authenticated-Sender: ecbiz194.inmotionhosting.com: everybody@....org
X-Source:
X-Source-Args:
X-Source-Dir:
X-Authority-Analysis: v=2.1 cv=Od5ldUnY c=1 sm=1 tr=0 p=tHMjoff1TzQA:10 a=BPsZ5WN3F+ptBTNoNLYonA==:117 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=9+rZDBEiDlHhcck0kWbJtElFXBc=:19 a=6Iz7jQTuP9IA:10 a=FqPqrT7mAAAA:8 a=wuaQj91YKeLcW_I7NZUA:9 a=FtJ_xtNkBE-qfxEx:21 a=wPNLvfGTeEIA:10 a=yozH4VhRfl4A:10 a=M3AHoUkWFckA:10 a=fZGknuNN1LOydenUCIb6:22
X-Cloudmark-Score: 100
X-RR-Connecting-IP: 107.14.64.106:25
Subject: SPAM: Lots of work today
X-Brightmail-Tracker: AAAAARZYL6Q=
X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrDqMTGxcIABLocC65FGFx/aGGx78B3FgdGj+Mv3jMFMEZx+OWXKAQXJOYmcGT07L7AVsBQAaIaGBlWMSqUlBYbF2cUJxYVF6RWGJjrpacW6xVX5ibmlaQm6yXn525ihJq+g3H7RZlTjJJS4ry3512LEBIoBpqYUQpUVxRfVJqTWvyKUZyDUUmYNxcky5OZV1KcmQ6TkeBgUhLhNdl4JUKIt7gkESEl1cDY81CZ25t3k/zUd21bd90/typmy6NtErw+Xs/YlXtk7atb4j4+/t6yoHDeJ3uN/kP1P7LrIiY5fFipZfynvvPJzbNfz943kPtyweqk3Tn/vpOfGIosVIpPxHht7j+Rl24XEH2vJa1o/q3fJRonvyxi6D4x60xlW8M/o0oLBlvjw4672ZjKQg2UWIozEg21mIuKEwGcu2V6TwEAAA==

This is a multi-part message in MIME format.
--------------3D4FAACFC2C069EFCDAE6DC6
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit

This is the text message

--------------3D4FAACFC2C069EFCDAE6DC6
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 8bit

<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>This is the text message <br>
    </p>
  </body>
</html>

--------------3D4FAACFC2C069EFCDAE6DC6--
</code>```

ContentLicense: CC BY-SA 3.0

Title: PHPMailer - forward email to group

Body:
I have a need for everyone in my organization to send emails to everyone else in the group.

As there are hundreds of members, and the membership changes often, it is not practical to use the traditional CPanel email forwarding method.  So I thought I would pipe the email to a php script, get all the members’ email addresses from the database (checking to make sure the original sender was also in the database) and send on the email to all members using PHPMailer.

I parsed the header in the PHP script to get the From, Subject (adding these of course to PHPMailer), Content-Type, and boundary.  Then I collected the actual email message in a variable $message including the lines that say (in this case)

“This is a multi-part message in MIME format.
--------------3D4FAACFC2C069EFCDAE6DC6, etc.  (This is of course in text format.)

Just before the PHPMailer Send command, I included:

$mail -> IsHTML(false);
// (I also tried not including this command at all – no change)
$mail->Body =$message;
$mail->addCustomHeader("Content-Type", $content_type . "  boundary=" . $boundary);

 $content_type and $boundary are the variables I parsed from the original header

As this is still in development, I sent the email to my address only.  It was received and displayed properly (both the plain and html as usual), but was marked as Spam – the received Header had the Subject already marked as Spam so I assume PHPMailer did it.

I noticed on the received Header that my custom header appeared correctly:

 Content-Type: multipart/alternative;  boundary="------------3D4FAACFC2C069EFCDAE6DC6"

The received header also had another Content-Type: text/plain; charset=iso-8859-1 after the above which I assume PHPMailer added.  Maybe the two Content-Types is what triggered the Spam tag.  I then tried adding $mail->header_remove ('Content-Type'); after the Body call and before addCustomHeader, but the additional  Content-Type: text/plain; charset=iso-8859-1 was still in the received header and it was still marked as Spam.

I am using PHPMailer version 5.2.22, and using

$mail->IsSMTP();
, $mail->SMTPAuth = true;
$mail->SMTPSecure = 'ssl';

I can’t continue to unsuccessfully experiment forever as I am afraid sending lots of Spam emails will get me in trouble, so I am hoping someone can tell what I am doing wrong, or even if my overall strategy is flawed.   I wish also there was a way to get the header that PHPMailer is going to use before it actually sends out the mail.

Note: my organization is a charitable group with little money, so we can't afford paid SMTP's.  I've tried using the free versions of some on the market (not for the above project) but given you are using a shared IP with many others using the free service you often get emails kicked back because others sharing your IP have been Spam tagged

Thanks

Body:
This is the entire header (I deleted some of the content just to keep this note a bit brief) that I received to my personal email (b...@....com) from my "forward email" script which uses everybody@....org as the originating address.  You can see the Content_Type I added to PHPMailer via $mail->addCustomHeader("Content-Type", $content_type . "  boundary=" . $boundary);(which is the multipart.. line) and the one PHPMailer itself added (text/plain...).  The email was received fine and displayed properly except for the Spam added to the Subject line:

From - Sat Mar 25 12:51:13 2017
STUFF
Return-Path: <everybody@....org>
Received: from dnvrco-pub-iedge-vip.email.rr.com ([107.14.70.244])
          by dnvrco-fep06.email.rr.com
          (InterMail vM.8.04.03.24 201-2389-100-172-20151028) with ESMTP
          id <20170325165112.EUNA23395.dnvrco-fep06.email.rr.com@dnvrco-pub-iedge-vip.email.rr.com>
          for <bmadder@...>; Sat, 25 Mar 2017 16:51:12 +0000
Return-Path: <everybody@....org>
Received: from [173.205.126.142] ...
Received: from ecbiz194.inmotionhosting.com .....
Date: Sat, 25 Mar 2017 12:51:01 -0400
To: b...@....com
From: everybody@....org
Message-ID: ...
Content-Type: multipart/alternative;  boundary="------------3D4FAACFC2C069EFCDAE6DC6"
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
X-OutGoing-Spam-Status: No, score=-1.0
X-AntiAbuse:...
X-Get-Message-Sender-Via: ecbiz194.inmotionhosting.com: authenticated_id: everybody@....org
X-Authenticated-Sender: ecbiz194.inmotionhosting.com: everybody@....org
X-Source:
X-Source-Args:
X-Source-Dir:
X-Authority-Analysis: v=2.1 cv=Od5ldUnY c=1 sm=1 tr=0 p=tHMjoff1TzQA:10 a=BPsZ5WN3F+ptBTNoNLYonA==:117 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=9+rZDBEiDlHhcck0kWbJtElFXBc=:19 a=6Iz7jQTuP9IA:10 a=FqPqrT7mAAAA:8 a=wuaQj91YKeLcW_I7NZUA:9 a=FtJ_xtNkBE-qfxEx:21 a=wPNLvfGTeEIA:10 a=yozH4VhRfl4A:10 a=M3AHoUkWFckA:10 a=fZGknuNN1LOydenUCIb6:22
X-Cloudmark-Score: 100
X-RR-Connecting-IP: 107.14.64.106:25
Subject: SPAM: Lots of work today
X-Brightmail-Tracker: AAAAARZYL6Q=
X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrDqMTGxcIABLocC65FGFx/aGGx78B3FgdGj+Mv3jMFMEZx+OWXKAQXJOYmcGT07L7AVsBQAaIaGBlWMSqUlBYbF2cUJxYVF6RWGJjrpacW6xVX5ibmlaQm6yXn525ihJq+g3H7RZlTjJJS4ry3512LEBIoBpqYUQpUVxRfVJqTWvyKUZyDUUmYNxcky5OZV1KcmQ6TkeBgUhLhNdl4JUKIt7gkESEl1cDY81CZ25t3k/zUd21bd90/typmy6NtErw+Xs/YlXtk7atb4j4+/t6yoHDeJ3uN/kP1P7LrIiY5fFipZfynvvPJzbNfz943kPtyweqk3Tn/vpOfGIosVIpPxHht7j+Rl24XEH2vJa1o/q3fJRonvyxi6D4x60xlW8M/o0oLBlvjw4672ZjKQg2UWIozEg21mIuKEwGcu2V6TwEAAA==

This is a multi-part message in MIME format.
--------------3D4FAACFC2C069EFCDAE6DC6
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit

This is the text message

--------------3D4FAACFC2C069EFCDAE6DC6
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 8bit

<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>This is the text message <br>
    </p>
  </body>
</html>

--------------3D4FAACFC2C069EFCDAE6DC6--


问:
Use the same socket.io connection in multiple HTML pages in node js
-Follwing is the jquery code I have written in my (dashboard.html) file

```<code><script>
 $(function(){

 $("#username").hide();
var socket= io.connect();

$(document).on("click", ".help", function () {

    alert( $(this).attr('id'));
    socket.emit('help',{helper:$username.val(),requester:$(this).attr('id')});
});
});
</code>```

---On clicking help button socket will emit an event "help" as you can see in the code.

---Following is the app.js file on server

```<code>    io.sockets.on('connection',function(socket){
   socket.on('help',function(data){
    console.log('rohi is goood',data.helper);
    socket.emit('loadList' , {helper:data.helper,requester:data.requester});

});
});
</code>```

---On "help" event socket is emitting an event "loadList" in app.js file.
   Now I want to use "loadList" event in some other html file like            "chat.html".
   The code I have written is as follows for chat.html.

```<code>  <script>

      $(function(){

     // var socket= io.connect();

   // var socket= io.connect('http://localhost:3000/', { 'force new //connection': true });

socket.on('loadList',function(data){
    alert('inside help',$('#usernam').val());
    console.log('tatai',$('#usernam').val());
    if($('#usernam').val()== data.helper){
        $('#chatList').append('<p>'+data.requester+'</p>'+'<button value="chat"></button>');
    }
   else if($('#usernam').val() == data.requester){
                    $('#chatList').append('<p>'+data.helper+'</p>'+'<button value="chat"></button>');

    }
    else {
        alert('fuck off');
    }

});
</code>```

The above code is not working. Please tell me how can I use same socket connection in the chat.html file.(loadList event is not working).

答:
As your question is not complete so i am assuming you want to know if socket.io connection can be used on different html pages . Yes you can access it on every html page of your application as long as you have one server on which socket.io is used . </p>

<p>Every time a new user comes a socket session is created for that particular user and that user can access any page of your application . </p>

Body:
As your question is not complete so i am assuming you want to know if socket.io connection can be used on different html pages . Yes you can access it on every html page of your application as long as you have one server on which socket.io is used .

Every time a new user comes a socket session is created for that particular user and that user can access any page of your application .


问:
Integrating Facebook and Twitter in Xcode Scenes Swift iOS
I have developed a game in Xcode using sprite kit, and scenes. Now I am trying to integrate the functionality to post high scores to twitter and Facebook. I've looked around, and most people say to use SLComposeServiceViewController which is fine, until I try and present it. Because my app really only uses scenes, they never have the member function "presentViewController(....)". Thus, I am unable to ever present it. Anyone know any way around this?</p>

```<code>override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    let touch:UITouch = touches.first!
    let touchLocation = touch.location(in: self)
    let touchedNode = self.atPoint(touchLocation)

    if (touchedNode.name == "tryAgain") {
        let nextScene = Scene_LiveGame(size: self.scene!.size)
        nextScene.scaleMode = self.scaleMode
        self.view?.presentScene(nextScene, transition: SKTransition.fade(withDuration: 0.5))
    }
    else if (touchedNode.name == "share") {

        if SLComposeViewController.isAvailable(forServiceType: SLServiceTypeFacebook) {

        let fShare = SLComposeViewController(forServiceType: SLServiceTypeFacebook)

        self.presentViewController(fShare!, animated: true, completion: nil)
         //^This is where my problem is. Xcode is telling me that self has no member function presentViewController which I totally understand, because its a scene and thus doesn't share those functions. But every resource online has shown me this is the only way to do it

        }

    }
</code>```

答:
I will not go into SLComposeViewController related code. I will just show you two techniques aside from what crashoverride777 proposed. So the first technique would be using notifications, like this:

GameScene:

```<code>import SpriteKit

let kNotificationName = "myNotificationName"

class GameScene: SKScene {

    private func postNotification(named name:String){

        NotificationCenter.default.post(
            Notification(name: Notification.Name(rawValue: name),
                         object: self,
                         userInfo: ["key":"value"]))
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        self.postNotification(named: kNotificationName)

    }
}
</code>```

Here, you post a notification by tapping the screen. A desired view controller class can listen for this notification, like this:

```<code>import UIKit
import SpriteKit

class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(self.handle(notification:)),
            name: NSNotification.Name(rawValue: kNotificationName),
            object: nil)

        if let view = self.view as! SKView? {
            // Load the SKScene from 'GameScene.sks'
            if let scene = GameScene(fileNamed: "GameScene") {
                // Set the scale mode to scale to fit the window
                scene.scaleMode = .aspectFill

                // Present the scene
                view.presentScene(scene)
            }
        }
    }

    func handle(notification:Notification){
        print("Notification : \(notification)")
    }
}
</code>```

Here, we add self as an observer for this notification - means that when notification happens, an appropriate handling method will be called (and that is our custom handle(notification:) method. In that method, you should call your code:

```<code>if SLComposeViewController.isAvailable(forServiceType:   SLServiceTypeFacebook) {
     let fShare = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
     self.presentViewController(fShare!, animated: true,  completion: nil)
}
</code>```

Actually, I will write another example for delegation, to keep things clean :)

Body:
I have developed a game in Xcode using sprite kit, and scenes. Now I am trying to integrate the functionality to post high scores to twitter and Facebook. I've looked around, and most people say to use SLComposeServiceViewController which is fine, until I try and present it. Because my app really only uses scenes, they never have the member function "presentViewController(....)". Thus, I am unable to ever present it. Anyone know any way around this?

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    let touch:UITouch = touches.first!
    let touchLocation = touch.location(in: self)
    let touchedNode = self.atPoint(touchLocation)

    if (touchedNode.name == "tryAgain") {
        let nextScene = Scene_LiveGame(size: self.scene!.size)
        nextScene.scaleMode = self.scaleMode
        self.view?.presentScene(nextScene, transition: SKTransition.fade(withDuration: 0.5))
    }
    else if (touchedNode.name == "share") {

        if SLComposeViewController.isAvailable(forServiceType: SLServiceTypeFacebook) {

        let fShare = SLComposeViewController(forServiceType: SLServiceTypeFacebook)

        self.presentViewController(fShare!, animated: true, completion: nil)
         //^This is where my problem is. Xcode is telling me that self has no member function presentViewController which I totally understand, because its a scene and thus doesn't share those functions. But every resource online has shown me this is the only way to do it

        }

    }

Body:
I will not go into SLComposeViewController related code. I will just show you two techniques aside from what crashoverride777 proposed. So the first technique would be using notifications, like this:

GameScene:

import SpriteKit

let kNotificationName = "myNotificationName"

class GameScene: SKScene {

    private func postNotification(named name:String){

        NotificationCenter.default.post(
            Notification(name: Notification.Name(rawValue: name),
                         object: self,
                         userInfo: ["key":"value"]))
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        self.postNotification(named: kNotificationName)

    }
}

Here, you post a notification by tapping the screen. A desired view controller class can listen for this notification, like this:

import UIKit
import SpriteKit

class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(self.handle(notification:)),
            name: NSNotification.Name(rawValue: kNotificationName),
            object: nil)

        if let view = self.view as! SKView? {
            // Load the SKScene from 'GameScene.sks'
            if let scene = GameScene(fileNamed: "GameScene") {
                // Set the scale mode to scale to fit the window
                scene.scaleMode = .aspectFill

                // Present the scene
                view.presentScene(scene)
            }
        }
    }

    func handle(notification:Notification){
        print("Notification : \(notification)")
    }
}

Here, we add self as an observer for this notification - means that when notification happens, an appropriate handling method will be called (and that is our custom handle(notification:) method. In that method, you should call your code:

if SLComposeViewController.isAvailable(forServiceType:   SLServiceTypeFacebook) {
     let fShare = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
     self.presentViewController(fShare!, animated: true,  completion: nil)
}

Actually, I will write another example for delegation, to keep things clean :)


问:
R Shiny REST API communication
I have a shiny app that takes a JSON input file, runs it through a classifier and returns a classified JSON object.
I want the app to be able to communicate with an API. I want the API to post a file to the Shiny App which will do its work and return a classified object.
Basically I want the Shiny app to sit in the background until a file is posted and then do its work.
I know that I can use GET from the httr package to get a file from a url. I can put this in the shiny.server file which is fine if I know the file name for the get command

However the filenames coming from the API will be different. So is there any way that I can make this dynamic according to the Post request that comes from the API.

答: If you do not have to use Shiny, you can use openCPU. OpenCPU provides each of your R packages as REST service automatically. I work with OpenCPU and it works fine! It is the easiest way to use R from another program.

ContentLicense: CC BY-SA 4.0

Title: R Shiny REST API communication


问:
EntityFrameworkCore using wrong column in query
I am trying to write my first web api with .net core.  I am using VS2017 and core 1.1.  I've got everything working except for one of my objects (I've tried it with that last line commented and uncommented...it makes no difference):

```<code>public class Tag
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool ShowInFilter { get; set; }
    public ICollection<SubscriberTag> SubscriberTags { get; set; }
}
</code>```

My repository code looks like this:

```<code>private SubscriptionContext db;
public TagRepository(SubscriptionContext context) { db = context; }
public Tag Find(int key) => db.Tags.SingleOrDefault(a => a.ID == key);
</code>```

That is being called from my TagController:

```<code>private iTagRepository TagItems { get; set; }
public TagController(iTagRepository tagItems) {TagItems = tagItems; }

[HttpGet("{id}", Name = "GetTag")]
public IActionResult Get(int id) { return new ObjectResult( TagItems.Find(id) ); }
</code>```

The problem is when I run it, the query that is executed is:

```<code>exec sp_executesql
N'SELECT TOP(2) [a].[ID], [a].[Name],
    [a].[ShowInFilter], [a].[SubscriberID]
FROM [Tags] AS [a]
WHERE [a].[ID] = @__key_0',N'@__key_0 int',@__key_0=1
</code>```

which throw and error because Tags doesn't contain a column called SubscriberID.
I've searched all my code and SubscriberID only shows up two places (in other classes which are not being used here).  I have no partial classes in my entire project (saw that was an issue on a related question.)

Why is EF adding this column to its query and how do I fix it?

As requested here is the class that contains subscriberID:

```<code>public class SubscriberTag
{
    public long ID { get; set; }
    public long subscriberID { get; set; }
    public int tagID { get; set; }

    public Subscriber Subscriber { get; set; }
    public Tag Tag { get; set; }
}
</code>```

Subscriber class (lots of irrelevant properties removed):

```<code>public class Subscriber
{
    public Subscriber()
    {
        //a few value initalizers/defaults
    }

    public long ID { get; set; }
    [StringLength(200)]
    public string FirstName { get; set; }
    //.......

    public ICollection<Subscribers.Models.Subscription> Subscriptions { get; set; }
    public ICollection<Subscribers.Models.Tag> Tags { get; set; }
}
</code>```

答:
Because of the Property Tags on Subscriber:

```<code>public ICollection<Subscribers.Models.Tag> Tags { get; set; }
</code>```

Entity Framework expects the Tag object to have a foreign-key to Subscriber so it builds a query with it. It looks like to configure the many-to-many relationship needs to change the property to:

```<code>public ICollection<Subscribers.Models.SubscriberTag> SubscriberTag{ get; set; }
</code>```

Configuring a Many-to-Many Relationship.

Thanks for the insight Ivan

Body:
I am trying to write my first web api with .net core.  I am using VS2017 and core 1.1.  I've got everything working except for one of my objects (I've tried it with that last line commented and uncommented...it makes no difference):

public class Tag
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool ShowInFilter { get; set; }
    public ICollection<SubscriberTag> SubscriberTags { get; set; }
}

My repository code looks like this:

private SubscriptionContext db;
public TagRepository(SubscriptionContext context) { db = context; }
public Tag Find(int key) => db.Tags.SingleOrDefault(a => a.ID == key);

That is being called from my TagController:

private iTagRepository TagItems { get; set; }
public TagController(iTagRepository tagItems) {TagItems = tagItems; }

[HttpGet("{id}", Name = "GetTag")]
public IActionResult Get(int id) { return new ObjectResult( TagItems.Find(id) ); }

The problem is when I run it, the query that is executed is:

exec sp_executesql
N'SELECT TOP(2) [a].[ID], [a].[Name],
    [a].[ShowInFilter], [a].[SubscriberID]
FROM [Tags] AS [a]
WHERE [a].[ID] = @__key_0',N'@__key_0 int',@__key_0=1

which throw and error because Tags doesn't contain a column called SubscriberID.
I've searched all my code and SubscriberID only shows up two places (in other classes which are not being used here).  I have no partial classes in my entire project (saw that was an issue on a related question.)

Why is EF adding this column to its query and how do I fix it?

As requested here is the class that contains subscriberID:

public class SubscriberTag
{
    public long ID { get; set; }
    public long subscriberID { get; set; }
    public int tagID { get; set; }

    public Subscriber Subscriber { get; set; }
    public Tag Tag { get; set; }
}

Subscriber class (lots of irrelevant properties removed):

public class Subscriber
{
    public Subscriber()
    {
        //a few value initalizers/defaults
    }

    public long ID { get; set; }
    [StringLength(200)]
    public string FirstName { get; set; }
    //.......

    public ICollection<Subscribers.Models.Subscription> Subscriptions { get; set; }
    public ICollection<Subscribers.Models.Tag> Tags { get; set; }
}

Body:
Because of the Property Tags on Subscriber:

public ICollection<Subscribers.Models.Tag> Tags { get; set; }

Entity Framework expects the Tag object to have a foreign-key to Subscriber so it builds a query with it. It looks like to configure the many-to-many relationship needs to change the property to:

public ICollection<Subscribers.Models.SubscriberTag> SubscriberTag{ get; set; }

Configuring a Many-to-Many Relationship.

Thanks for the insight Ivan


问:
PubNub channelGroup.forEach is not a function
I'm working with PubNub for a secure messaging system and I'm running into problems with the channel listing returning a 'not a function error'. Here is my code for this:

```<code>$(document).on("pageshow", "#vendorMessages", function(event, ui) {
    var channelGroup = String(window.vendorID);
    pubnub.subscribe({
        channelGroups: channelGroup
    })
    pubnub.channelGroups.listChannels({
            channelGroup: channelGroup
        },
        function (status, response) {
            console.log("listing push channel for device")
            response.channels.forEach( function (channel) {
                console.log(channel)
            })
            response.channels.forEach( function (channel) {
                var channelFormatted = String(channel).split("_");
                var channelMember = channelFormatted[1];
                var e = $("#channelResults");
                e.append("<li onClick='loadChannel("+channel+")>"+channelFormatted+"</li>");
                e.listview("refresh");
            })
        }
    )
})
</code>```

It is returning this error:

```<code>Uncaught TypeError: channelGroups.forEach is not a function
    at _class.adaptSubscribeChange (https://cdn.pubnub.com/sdk/javascript/pubnub.4.4.4.js:3392:22)
    at HTMLDivElement.<anonymous> (http://www.weddingindustryinsider.com/www/index.html:504:10)
    at HTMLDocument.dispatch (https://code.jquery.com/jquery-1.11.1.js:4641:9)
    at HTMLDocument.elemData.handle (https://code.jquery.com/jquery-1.11.1.js:4309:28)
    at Object.trigger (https://code.jquery.com/jquery-1.11.1.js:4550:12)
    at HTMLDivElement.<anonymous> (https://code.jquery.com/jquery-1.11.1.js:5260:17)
    at Function.each (https://code.jquery.com/jquery-1.11.1.js:383:23)
    at jQuery.fn.init.each (https://code.jquery.com/jquery-1.11.1.js:136:17)
    at jQuery.fn.init.trigger (https://code.jquery.com/jquery-1.11.1.js:5259:15)
    at $.(anonymous function).(anonymous function)._triggerWithDeprecated (https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js:5020:29)
</code>```

Any help would be greatly appreciated.

答:
I had a similar problem.
The problem is that channels, or channelGroups parameters should be an array.

Replace:

```<code>var channelGroup = String(window.vendorID);
</code>```

By:

```<code>var channelGroup = [String(window.vendorID)];
</code>```

Body:
I'm working with PubNub for a secure messaging system and I'm running into problems with the channel listing returning a 'not a function error'. Here is my code for this:

$(document).on("pageshow", "#vendorMessages", function(event, ui) {
    var channelGroup = String(window.vendorID);
    pubnub.subscribe({
        channelGroups: channelGroup
    })
    pubnub.channelGroups.listChannels({
            channelGroup: channelGroup
        },
        function (status, response) {
            console.log("listing push channel for device")
            response.channels.forEach( function (channel) {
                console.log(channel)
            })
            response.channels.forEach( function (channel) {
                var channelFormatted = String(channel).split("_");
                var channelMember = channelFormatted[1];
                var e = $("#channelResults");
                e.append("
"+channelFormatted+"
");
                e.listview("refresh");
            })
        }
    )
})

It is returning this error:

Uncaught TypeError: channelGroups.forEach is not a function
    at _class.adaptSubscribeChange (https://cdn.pubnub.com/sdk/javascript/pubnub.4.4.4.js:3392:22)
    at HTMLDivElement.<anonymous> (http://www.weddingindustryinsider.com/www/index.html:504:10)
    at HTMLDocument.dispatch (https://code.jquery.com/jquery-1.11.1.js:4641:9)
    at HTMLDocument.elemData.handle (https://code.jquery.com/jquery-1.11.1.js:4309:28)
    at Object.trigger (https://code.jquery.com/jquery-1.11.1.js:4550:12)
    at HTMLDivElement.<anonymous> (https://code.jquery.com/jquery-1.11.1.js:5260:17)
    at Function.each (https://code.jquery.com/jquery-1.11.1.js:383:23)
    at jQuery.fn.init.each (https://code.jquery.com/jquery-1.11.1.js:136:17)
    at jQuery.fn.init.trigger (https://code.jquery.com/jquery-1.11.1.js:5259:15)
    at $.(anonymous function).(anonymous function)._triggerWithDeprecated (https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js:5020:29)

Any help would be greatly appreciated.

Body:
I had a similar problem.
The problem is that channels, or channelGroups parameters should be an array.

Replace:

var channelGroup = String(window.vendorID);

By:

var channelGroup = [String(window.vendorID)];


问:
Javascript strings and objects
In js can I call a function in an object from a string? Hm, I show you with an example:

```<code>var Object = {
    callMe : function() { }
}

Object.callMe();
</code>```

This I can do, but what if I want to do this:

```<code>var string = 'callMe';
Object.string();
</code>```

Can I somehow do this? Maybe I'm just thinking wrong here

答:
```<code>var myObject = {
  myFunction: function() { return "Hooray!"; }
}

var methodName = "myFunction";

alert( myObject[methodName]() );
</code>```

ContentLicense: CC BY-SA 2.5

Title: Javascript strings and objects

Body:
In js can I call a function in an object from a string? Hm, I show you with an example:

var Object = {
    callMe : function() { }
}

Object.callMe();

This I can do, but what if I want to do this:

var string = 'callMe';
Object.string();

Can I somehow do this? Maybe I'm just thinking wrong here


问:
How can add a new column in df1 called value that looks up the value from df2 based on the year column?
I have two DataFrames,

df1

```<code>Name    Year
A       2008
A       2009
B       2008
B       2008
</code>```

df2

```<code>year    value
2008    10
2009    15
</code>```

How can add a new column in df1 called value that looks up the value from df2 based on the year column?

Goal

```<code>Name  Year  Value
A     2008  10
A     2009  15
B     2008  10
B     2009  15
</code>```

My issue ended up being datatypes..

```<code> df = df.convert_objects(convert_numeric=True)
</code>```

The map solution was the fastest with 76,000 rows

答:
You can use map

```<code>df1['value'] = df1['Year'].map(df2.set_index('year')['value'])
</code>```

You get

```<code>    Name    Year    value
0   A       2008    10
1   A       2009    15
2   B       2008    10
3   B       2008    10
</code>```

Body:
I have two DataFrames,

df1

Name    Year
A       2008
A       2009
B       2008
B       2008

df2

year    value
2008    10
2009    15

How can add a new column in df1 called value that looks up the value from df2 based on the year column?

Goal

Name  Year  Value
A     2008  10
A     2009  15
B     2008  10
B     2009  15

My issue ended up being datatypes..

 df = df.convert_objects(convert_numeric=True)

The map solution was the fastest with 76,000 rows

Body:
You can use map

df1['value'] = df1['Year'].map(df2.set_index('year')['value'])

You get

    Name    Year    value
0   A       2008    10
1   A       2009    15
2   B       2008    10
3   B       2008    10


问:
Postgres time zones and formatting
I know there are some similar questions about this, but I'm having a hard time understanding why my database is formatting times the way it is.

I have a field called created_at and in the database the value is:

```<code>2017-03-30 11:01:25.976-04
</code>```

It's 11am New York time, with a four-hour negative offset from UTC.

I want it to display as 11:01am. When I use TO_CHAR() to format it, though, it converts the time to UTC and shows 3:01pm.

```<code>SELECT to_char(ledger.created_at, 'Mon DD YYYY HH12: MI AM') AS formatted_date ...
</code>```

I can fix this by adding AT TIME ZONE 'America/New_York' but I don't like the idea of hard-coding that in my application.

```<code>SELECT to_char(ledger.created_at AT TIME ZONE 'America/New_York', 'Mon DD YYYY HH12: MI AM') AS formatted_date ...
</code>```

It seems like the timestamp field knows what time it is already, and what time zone it's in (or at least the offset amount) and it displays 11am in the database itself.

I also know I can SET the local time before each query and it will work, but again I'm wondering if there's an easier way. It seems like maybe I could strip the timezone information and just get the 11:01am time that's in the database. If there isn't a way, I can live with it, but I needed to check.

For context, this is within a Node and Express app using Sequelize.

答:
PostgreSQL doesn't store the time zone, it stores timestamp with time zone as UTC timestamp.

Upon retrieval it is converted to the time zone in effect in the database session (set with SET TimeZone = '...').

So to convert it to a string at a certain time zone, there are two ways:

Adjust the session time zone with SET TimeZone = '...'.

Explicitly specify the time zone with AT TIME ZONE.

From your question I deduce that your session time zone is set to UTC.

You have to specify the desired time zone somewhere...

Title: Postgres time zones and formatting

Body:
I know there are some similar questions about this, but I'm having a hard time understanding why my database is formatting times the way it is.

I have a field called created_at and in the database the value is:

2017-03-30 11:01:25.976-04

It's 11am New York time, with a four-hour negative offset from UTC.

I want it to display as 11:01am. When I use TO_CHAR() to format it, though, it converts the time to UTC and shows 3:01pm.

SELECT to_char(ledger.created_at, 'Mon DD YYYY HH12: MI AM') AS formatted_date ...

I can fix this by adding AT TIME ZONE 'America/New_York' but I don't like the idea of hard-coding that in my application.

SELECT to_char(ledger.created_at AT TIME ZONE 'America/New_York', 'Mon DD YYYY HH12: MI AM') AS formatted_date ...

It seems like the timestamp field knows what time it is already, and what time zone it's in (or at least the offset amount) and it displays 11am in the database itself.

I also know I can SET the local time before each query and it will work, but again I'm wondering if there's an easier way. It seems like maybe I could strip the timezone information and just get the 11:01am time that's in the database. If there isn't a way, I can live with it, but I needed to check.

For context, this is within a Node and Express app using Sequelize.


问:
How to define a general recurrence function in Clojure
I had an idea for a general function for recurrence relations in Clojure:

```<code>(defn recurrence [f inits]
  (let [answer (lazy-seq (recurrence f inits))
        windows (partition (count inits) 1 answer)]
    (concat inits (lazy-seq (map f windows)))))
</code>```

Then, for example, we can define the Fibonacci sequence as

```<code>(def fibs (recurrence (partial apply +) [0 1N]))
</code>```

This works well enough for small numbers:

```<code>(take 10 fibs)
;(0 1N 1N 2N 3N 5N 8N 13N 21N 34N)
</code>```

But it blows the stack if asked to realise a long sequence:

```<code>(first (drop 10000 fibs))
;StackOverflowError ...
</code>```

Is there any way to overcome this?

Body:
I had an idea for a general function for recurrence relations in Clojure:

(defn recurrence [f inits]
  (let [answer (lazy-seq (recurrence f inits))
        windows (partition (count inits) 1 answer)]
    (concat inits (lazy-seq (map f windows)))))

Then, for example, we can define the Fibonacci sequence as

(def fibs (recurrence (partial apply +) [0 1N]))

This works well enough for small numbers:

(take 10 fibs)
;(0 1N 1N 2N 3N 5N 8N 13N 21N 34N)

But it blows the stack if asked to realise a long sequence:

(first (drop 10000 fibs))
;StackOverflowError ...

Is there any way to overcome this?

Body:
Starting from the accepted answer.

We want to start the sequence with the seed.

As the author suggests, we use a queue for efficiency. There's no need for a deque:  clojure's PersistentQueue is all we need.

The adapted recurrence might look like this:

(defn recurrence
  [f seed]
  (let [init-window (into (clojure.lang.PersistentQueue/EMPTY) seed)
        unroll (fn unroll [w] (lazy-seq (cons
                                          (peek w)
                                          (unroll (-> w
                                                      pop
                                                      (conj (apply f w)))))))]
    (unroll init-window)))

... and, as before ...

(def fibs (recurrence +' [0 1]))

Then

(take 12 fibs)
;(0 1 1 2 3 5 8 13 21 34 55 89)

and

(first (drop 10002 fibs))
;88083137989997064605355872998857923445691333015376030932812485815888664307789011385238647061572694566755888008658862476758094375234981509702215595106015601812940878487465890539696395631360292400123725490667987980947195761919733084221263262792135552511961663188744083262743015393903228035182529922900769207624088879893951554938584166812233127685528968882435827903110743620870056104022290494963321073406865860606579792362403866826411642270661211435590340090149458419810817251120025713501918959350654895682804718752319215892119222907223279849851227166387954139546662644064653804466345416102543306712688251378793506564112970620367672131344559199027717813404940431009754143637417645359401155245658646088296578097547699141284451819782703782878668237441026255023475279003880007450550868002409533068098127495095667313120369142331519140185017719214501847645741030739351025342932514280625453085775191996236343792432215700850773568257988920265539647922172315902209901079830195949058505943508013044450503826167880993094540503572266189964694973263576375908606977788395730196227274629745722872833622300472769312273603346624292690875697438264265712313123637644491367875538847442013130532147345613099333195400845560466085176375175045485046787815133225349388996334014329318304865656815129208586686515835880811316065788759195646547703631454040090435955879604123186007481842117640574158367996845627012099571008761776991075470991386301988104753915798231741447012236434261594666985397841758348337030914623617101746431922708522824868155612811426016775968762121429282582582088871795463467796927317452368633552346819405423359738696980252707545944266042764236577381721803749442538053900196250284054406347238606575093877669323501452512412179883698552204038865069179867773579705703841178650618818357366165649529547898801198617541432893443650952033983923542592952070864044249738338089778163986683069566736505126466886304227253105034231716761535350441178724210841830855527586882822093246545813120624113290391593897765219320931179697869997243770533719319530526369830529543842405655495229382251039116426750156771132964376N

Another way, based on an idea stolen - I think - from Joy of Clojure, is ...

(defn recurrence
  [f seed]
  (let [init-window (into (clojure.lang.PersistentQueue/EMPTY) seed)
        windows (iterate
                  (fn [w] (-> w, pop, (conj (apply f w))))
                  init-window)]
    (map peek windows)))


问:
J2ME Read ID3 Tags From Walkman (Sony Ericsson)
Is there any way to read the currently playing song title/artist (id3 tags) in walkman on sony ericsson (w series) phone?</p>

答:
you can get information of currently playing song by the using of player MetaDataControl class.
with the help of this u can find information like title,album,total time,content type etc.... </p>


问:
Computing distances using distCosine
I want to compute distances between couples of (lat,lon) coordinates, like in this example:
Calculating distances from latitude and longitude coordinates in R

but using dplyr in order to speed up the process, and using the distCosine function from geosphere.

This function accepts only vectors of size 2, and the only way I found that works is:

```<code>p <- data.frame(lat=runif(6,-90,90), lon=runif(6,-180,180),lat2=runif(6,-90,90), lon2=runif(6,-180,180) )
p$dist <- sapply(1:nrow(p), function(x) distCosine(c(p$lon[x], p$lat[x]), c(p$lon2[x], p$lat2[x]) ) )
</code>```

With dplyr I have tried:

```<code>p %>% rowwise() %>% mutate(dist2prev = distCosine(c(lon, lat), c(lon2, lat2)))
p %>% group_by(1:n()) %>% mutate(dist2prev = distCosine(c(lon, lat), c(lon2, lat2)))
</code>```

but the error is always the same:

```<code>Wrong length for a vector, should be 2
</code>```

Any idea why dplyr does not succeed there?

答:
If I give up on using distCosine and implement the function by myself I get a fast response as well with:</p>

```<code>dist <- function(lat1, lon1, lat2, lon2){
  r <- acos(sin(lat1) * sin(lat2) + cos(lat1)*cos(lat2) * cos(abs(lon2-lon1))) * 6378137
}
deg2rad <- function(deg) {(deg * pi) / (180)}

p %>% mutate(x = dist(deg2rad(lat1),deg2rad(lon1),deg2rad(lat2),deg2rad(lon2)))
</code>```

Title: Computing distances using distCosine

Body:
I want to compute distances between couples of (lat,lon) coordinates, like in this example:
Calculating distances from latitude and longitude coordinates in R

but using dplyr in order to speed up the process, and using the distCosine function from geosphere.

This function accepts only vectors of size 2, and the only way I found that works is:

p <- data.frame(lat=runif(6,-90,90), lon=runif(6,-180,180),lat2=runif(6,-90,90), lon2=runif(6,-180,180) )
p$dist <- sapply(1:nrow(p), function(x) distCosine(c(p$lon[x], p$lat[x]), c(p$lon2[x], p$lat2[x]) ) )

With dplyr I have tried:

p %>% rowwise() %>% mutate(dist2prev = distCosine(c(lon, lat), c(lon2, lat2)))
p %>% group_by(1:n()) %>% mutate(dist2prev = distCosine(c(lon, lat), c(lon2, lat2)))

but the error is always the same:

Wrong length for a vector, should be 2

Any idea why dplyr does not succeed there?

Body:
If I give up on using distCosine and implement the function by myself I get a fast response as well with:

dist <- function(lat1, lon1, lat2, lon2){
  r <- acos(sin(lat1) * sin(lat2) + cos(lat1)*cos(lat2) * cos(abs(lon2-lon1))) * 6378137
}
deg2rad <- function(deg) {(deg * pi) / (180)}

p %>% mutate(x = dist(deg2rad(lat1),deg2rad(lon1),deg2rad(lat2),deg2rad(lon2)))


问:
Attempt to present UIViewController on UIViewController whose view is not in the window hierarchy
Just started using Xcode 4.5 and I got this error in the console:

Warning: Attempt to present < finishViewController: 0x1e56e0a0 > on < ViewController: 0x1ec3e000> whose view is not in the window hierarchy!

The view is still being presented and everything in the app is working fine. Is this something new in iOS 6?

This is the code I'm using to change between views:

```<code>UIStoryboard *storyboard = self.storyboard;
finishViewController *finished =
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];

[self presentViewController:finished animated:NO completion:NULL];
</code>```

答:
I had this issue, and the root cause was subscribing to a button click handler (TouchUpInside) multiple times.

It was subscribing in ViewWillAppear, which was being called multiple times since we had added navigation to go to another controller, and then unwind back to it.

Body:
Just started using Xcode 4.5 and I got this error in the console:

Warning: Attempt to present < finishViewController: 0x1e56e0a0 > on < ViewController: 0x1ec3e000> whose view is not in the window hierarchy!

The view is still being presented and everything in the app is working fine. Is this something new in iOS 6?

This is the code I'm using to change between views:

UIStoryboard *storyboard = self.storyboard;
finishViewController *finished =
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];

[self presentViewController:finished animated:NO completion:NULL];


问:
InvalidArgumentException in FileViewFinder.php line 137: View [index] not found
I want to deploy my laravel App with OVH hosting. When I'm opening my website I get this, someone knows why ?

```<code>InvalidArgumentException in FileViewFinder.php line 137: View [index] not found.
</code>```

here is Fileviewfinder

```<code>    <?php

namespace Illuminate\View;

use InvalidArgumentException;
use Illuminate\Filesystem\Filesystem;

class FileViewFinder implements ViewFinderInterface
{
    /**
     * The filesystem instance.
     *
     * @var \Illuminate\Filesystem\Filesystem
     */
    protected $files;

    /**
     * The array of active view paths.
     *
     * @var array
     */
    protected $paths;

    /**
     * The array of views that have been located.
     *
     * @var array
     */
    protected $views = [];

    /**
     * The namespace to file path hints.
     *
     * @var array
     */
    protected $hints = [];

    /**
     * Register a view extension with the finder.
     *
     * @var array
     */
    protected $extensions = ['blade.php', 'php'];

    /**
     * Create a new file view loader instance.
     *
     * @param  \Illuminate\Filesystem\Filesystem  $files
     * @param  array  $paths
     * @param  array  $extensions
     * @return void
     */
    public function __construct(Filesystem $files, array $paths, array $extensions = null)
    {
        $this->files = $files;
        $this->paths = $paths;

        if (isset($extensions)) {
            $this->extensions = $extensions;
        }
    }

    /**
     * Get the fully qualified location of the view.
     *
     * @param  string  $name
     * @return string
     */
    public function find($name)
    {
        if (isset($this->views[$name])) {
            return $this->views[$name];
        }

        if ($this->hasHintInformation($name = trim($name))) {
            return $this->views[$name] = $this->findNamedPathView($name);
        }

        return $this->views[$name] = $this->findInPaths($name, $this->paths);
    }

    /**
     * Get the path to a template with a named path.
     *
     * @param  string  $name
     * @return string
     */
    protected function findNamedPathView($name)
    {
        list($namespace, $view) = $this->getNamespaceSegments($name);

        return $this->findInPaths($view, $this->hints[$namespace]);
    }

    /**
     * Get the segments of a template with a named path.
     *
     * @param  string  $name
     * @return array
     *
     * @throws \InvalidArgumentException
     */
    protected function getNamespaceSegments($name)
    {
        $segments = explode(static::HINT_PATH_DELIMITER, $name);

        if (count($segments) != 2) {
            throw new InvalidArgumentException("View [$name] has an invalid name.");
        }

        if (! isset($this->hints[$segments[0]])) {
            throw new InvalidArgumentException("No hint path defined for [{$segments[0]}].");
        }

        return $segments;
    }

    /**
     * Find the given view in the list of paths.
     *
     * @param  string  $name
     * @param  array   $paths
     * @return string
     *
     * @throws \InvalidArgumentException
     */
    protected function findInPaths($name, $paths)
    {
        foreach ((array) $paths as $path) {
            foreach ($this->getPossibleViewFiles($name) as $file) {
                if ($this->files->exists($viewPath = $path.'/'.$file)) {
                    return $viewPath;
                }
            }
        }

        throw new InvalidArgumentException("View [$name] not found.");
    }

    /**
     * Get an array of possible view files.
     *
     * @param  string  $name
     * @return array
     */
    protected function getPossibleViewFiles($name)
    {
        return array_map(function ($extension) use ($name) {
            return str_replace('.', '/', $name).'.'.$extension;

        }, $this->extensions);
    }

    /**
     * Add a location to the finder.
     *
     * @param  string  $location
     * @return void
     */
    public function addLocation($location)
    {
        $this->paths[] = $location;
    }

    /**
     * Add a namespace hint to the finder.
     *
     * @param  string  $namespace
     * @param  string|array  $hints
     * @return void
     */
    public function addNamespace($namespace, $hints)
    {
        $hints = (array) $hints;

        if (isset($this->hints[$namespace])) {
            $hints = array_merge($this->hints[$namespace], $hints);
        }

        $this->hints[$namespace] = $hints;
    }

    /**
     * Prepend a namespace hint to the finder.
     *
     * @param  string  $namespace
     * @param  string|array  $hints
     * @return void
     */
    public function prependNamespace($namespace, $hints)
    {
        $hints = (array) $hints;

        if (isset($this->hints[$namespace])) {
            $hints = array_merge($hints, $this->hints[$namespace]);
        }

        $this->hints[$namespace] = $hints;
    }

    /**
     * Register an extension with the view finder.
     *
     * @param  string  $extension
     * @return void
     */
    public function addExtension($extension)
    {
        if (($index = array_search($extension, $this->extensions)) !== false) {
            unset($this->extensions[$index]);
        }

        array_unshift($this->extensions, $extension);
    }

    /**
     * Returns whether or not the view specify a hint information.
     *
     * @param  string  $name
     * @return bool
     */
    public function hasHintInformation($name)
    {
        return strpos($name, static::HINT_PATH_DELIMITER) > 0;
    }

    /**
     * Get the filesystem instance.
     *
     * @return \Illuminate\Filesystem\Filesystem
     */
    public function getFilesystem()
    {
        return $this->files;
    }

    /**
     * Get the active view paths.
     *
     * @return array
     */
    public function getPaths()
    {
        return $this->paths;
    }

    /**
     * Get the namespace to file path hints.
     *
     * @return array
     */
    public function getHints()
    {
        return $this->hints;
    }

    /**
     * Get registered extensions.
     *
     * @return array
     */
    public function getExtensions()
    {
        return $this->extensions;
    }
}
</code>```

答:
Run the command "php artisan config:clear"
Then request again and a new "config.php" file will be created in "./bootstrap/cache/config.php" with the app settings</p>

Body:
I want to deploy my laravel App with OVH hosting. When I'm opening my website I get this, someone knows why ?

InvalidArgumentException in FileViewFinder.php line 137: View [index] not found.

here is Fileviewfinder

    <?php

namespace Illuminate\View;

use InvalidArgumentException;
use Illuminate\Filesystem\Filesystem;

class FileViewFinder implements ViewFinderInterface
{
    /**
     * The filesystem instance.
     *
     * @var \Illuminate\Filesystem\Filesystem
     */
    protected $files;

    /**
     * The array of active view paths.
     *
     * @var array
     */
    protected $paths;

    /**
     * The array of views that have been located.
     *
     * @var array
     */
    protected $views = [];

    /**
     * The namespace to file path hints.
     *
     * @var array
     */
    protected $hints = [];

    /**
     * Register a view extension with the finder.
     *
     * @var array
     */
    protected $extensions = ['blade.php', 'php'];

    /**
     * Create a new file view loader instance.
     *
     * @param  \Illuminate\Filesystem\Filesystem  $files
     * @param  array  $paths
     * @param  array  $extensions
     * @return void
     */
    public function __construct(Filesystem $files, array $paths, array $extensions = null)
    {
        $this->files = $files;
        $this->paths = $paths;

        if (isset($extensions)) {
            $this->extensions = $extensions;
        }
    }

    /**
     * Get the fully qualified location of the view.
     *
     * @param  string  $name
     * @return string
     */
    public function find($name)
    {
        if (isset($this->views[$name])) {
            return $this->views[$name];
        }

        if ($this->hasHintInformation($name = trim($name))) {
            return $this->views[$name] = $this->findNamedPathView($name);
        }

        return $this->views[$name] = $this->findInPaths($name, $this->paths);
    }

    /**
     * Get the path to a template with a named path.
     *
     * @param  string  $name
     * @return string
     */
    protected function findNamedPathView($name)
    {
        list($namespace, $view) = $this->getNamespaceSegments($name);

        return $this->findInPaths($view, $this->hints[$namespace]);
    }

    /**
     * Get the segments of a template with a named path.
     *
     * @param  string  $name
     * @return array
     *
     * @throws \InvalidArgumentException
     */
    protected function getNamespaceSegments($name)
    {
        $segments = explode(static::HINT_PATH_DELIMITER, $name);

        if (count($segments) != 2) {
            throw new InvalidArgumentException("View [$name] has an invalid name.");
        }

        if (! isset($this->hints[$segments[0]])) {
            throw new InvalidArgumentException("No hint path defined for [{$segments[0]}].");
        }

        return $segments;
    }

    /**
     * Find the given view in the list of paths.
     *
     * @param  string  $name
     * @param  array   $paths
     * @return string
     *
     * @throws \InvalidArgumentException
     */
    protected function findInPaths($name, $paths)
    {
        foreach ((array) $paths as $path) {
            foreach ($this->getPossibleViewFiles($name) as $file) {
                if ($this->files->exists($viewPath = $path.'/'.$file)) {
                    return $viewPath;
                }
            }
        }

        throw new InvalidArgumentException("View [$name] not found.");
    }

    /**
     * Get an array of possible view files.
     *
     * @param  string  $name
     * @return array
     */
    protected function getPossibleViewFiles($name)
    {
        return array_map(function ($extension) use ($name) {
            return str_replace('.', '/', $name).'.'.$extension;

        }, $this->extensions);
    }

    /**
     * Add a location to the finder.
     *
     * @param  string  $location
     * @return void
     */
    public function addLocation($location)
    {
        $this->paths[] = $location;
    }

    /**
     * Add a namespace hint to the finder.
     *
     * @param  string  $namespace
     * @param  string|array  $hints
     * @return void
     */
    public function addNamespace($namespace, $hints)
    {
        $hints = (array) $hints;

        if (isset($this->hints[$namespace])) {
            $hints = array_merge($this->hints[$namespace], $hints);
        }

        $this->hints[$namespace] = $hints;
    }

    /**
     * Prepend a namespace hint to the finder.
     *
     * @param  string  $namespace
     * @param  string|array  $hints
     * @return void
     */
    public function prependNamespace($namespace, $hints)
    {
        $hints = (array) $hints;

        if (isset($this->hints[$namespace])) {
            $hints = array_merge($hints, $this->hints[$namespace]);
        }

        $this->hints[$namespace] = $hints;
    }

    /**
     * Register an extension with the view finder.
     *
     * @param  string  $extension
     * @return void
     */
    public function addExtension($extension)
    {
        if (($index = array_search($extension, $this->extensions)) !== false) {
            unset($this->extensions[$index]);
        }

        array_unshift($this->extensions, $extension);
    }

    /**
     * Returns whether or not the view specify a hint information.
     *
     * @param  string  $name
     * @return bool
     */
    public function hasHintInformation($name)
    {
        return strpos($name, static::HINT_PATH_DELIMITER) > 0;
    }

    /**
     * Get the filesystem instance.
     *
     * @return \Illuminate\Filesystem\Filesystem
     */
    public function getFilesystem()
    {
        return $this->files;
    }

    /**
     * Get the active view paths.
     *
     * @return array
     */
    public function getPaths()
    {
        return $this->paths;
    }

    /**
     * Get the namespace to file path hints.
     *
     * @return array
     */
    public function getHints()
    {
        return $this->hints;
    }

    /**
     * Get registered extensions.
     *
     * @return array
     */
    public function getExtensions()
    {
        return $this->extensions;
    }
}


问:
New instance Foundation on setTimeout
I would lik programmatic use Sticky component of zurb Foundation framework, but asynchronous :

```<code>const sticky = new Foundation.Sticky($('.sticky'));
</code>```

If i run this code, it work nice. But with setTimeout, it don't work :

```<code>setTimeout(() => {
  const sticky = new Foundation.Sticky($('.sticky'));
}, 2000);
</code>```

You can test this on codepen.

Anyone can help me ? I don't know why my new instance don't work in async code.

Thank you !

答:
I recalculate the points by calling the _calc() methode of Sticky:

```<code>setTimeout(() => {
   const sticky = new Foundation.Sticky($('.sticky'));
   $('.sticky').foundation('_calc', true);
}, 2000);
</code>```

this worked in your codepen example.
I found the solution in the Github issue tracker of zurb / foundation-sites.

Title: New instance Foundation on setTimeout

Body:
I would lik programmatic use Sticky component of zurb Foundation framework, but asynchronous :

const sticky = new Foundation.Sticky($('.sticky'));

If i run this code, it work nice. But with setTimeout, it don't work :

setTimeout(() => {
  const sticky = new Foundation.Sticky($('.sticky'));
}, 2000);

You can test this on codepen.

Anyone can help me ? I don't know why my new instance don't work in async code.

Thank you !

Body:
I recalculate the points by calling the _calc() methode of Sticky:

setTimeout(() => {
   const sticky = new Foundation.Sticky($('.sticky'));
   $('.sticky').foundation('_calc', true);
}, 2000);

this worked in your codepen example.
I found the solution in the Github issue tracker of zurb / foundation-sites.


问:
How to properly center the text?
I'm trying to center the text in the middle of JQM page, vertically and horizontally. Using 1.4.5, default theme.

In my .css I have:

```<code>.splashDiv {
    position: absolute;
    top: 50%;
    height: 50%;
    width: 100%;
    text-align: center;
    padding:0;
}
</code>```

HTML

```<code><div class="splashDiv" data-role="page">
    Please wait...
</div>
</code>```

The result is:

The text is vertically centered only if I remove top: 0 directive in developer tools(although not perfectly centered).

My question is what is the proper way according to JQM architecture to have what I want? I am not looking for quick/dirty workaround, unless there is no other way.

UPDATE

答:
Put your splash div within a jQM page instead of making it the page:

```<code><div data-role="page" id="page1">
    <div id="cont" role="main" class="ui-content">
      <div class="splashDiv" >
          Please wait...
      </div>
   </div>
</div>

.splashDiv {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
</code>```

DEMO

Title: How to properly center the text?

Body:
I'm trying to center the text in the middle of JQM page, vertically and horizontally. Using 1.4.5, default theme.

In my .css I have:

.splashDiv {
    position: absolute;
    top: 50%;
    height: 50%;
    width: 100%;
    text-align: center;
    padding:0;
}

HTML

    Please wait...

The result is:

The text is vertically centered only if I remove top: 0 directive in developer tools(although not perfectly centered).

My question is what is the proper way according to JQM architecture to have what I want? I am not looking for quick/dirty workaround, unless there is no other way.

UPDATE

Body:
Put your splash div within a jQM page instead of making it the page:

<div data-role="page" id="page1">
    <div id="cont" role="main" class="ui-content">
      <div class="splashDiv" >
          Please wait...
      </div>
   </div>
</div>

.splashDiv {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

DEMO


问:
KOGrid Cell Template $parent is not defined
A beginner level javascript question...

I need to define a cell template for my KOGrid that is dependent on values in my VM. I want text to be displayed green if an associated field is True else display in red.

I have the following cell templates:

```<code>var accountEditTemplate = `<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[$data.field]" />
                                <span data-bind=\"visible: !$parent.selected(),
                                    text: $parent.entity[$data.field],
                                    css: $parent.entity.accountIsValid() === 'True' ? \'passed-validation\' : \'failed-validation\'">
                                </span>
                            </div>`;

    var costCentreEditTemplate = `<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[$data.field]" />
                                <span data-bind=\"visible: !$parent.selected(),
                                    text: $parent.entity[$data.field],
                                    css: $parent.entity.costCentreIsValid() === 'True' ? \'passed-validation\' : \'failed-validation\'">
                                </span>
                            </div>`;
</code>```

These get used in my columnDefs as follows

```<code>self.columnDefs = [
        { width: 100, field: 'supplierNo', displayName: 'Supplier No', cellTemplate: supplierEditTemplate },
        { width: 150, field: 'invoiceNo', displayName: 'Invoice No' },
        { width: 150, field: 'costCentre', displayName: 'Cost Centre (Dim1)', cellTemplate: costCentreEditTemplate },
        { width: 200, field: 'glAccount', displayName: 'GL Account (Account)', cellTemplate: accountEditTemplate },
        { width: 100, field: 'amount', displayName: 'Amount' },
        { width: 300, field: 'invoiceDesc', displayName: 'Invoice Description' },
        { width: 150, field: 'accountIsValid', displayName: 'Valid Account' },
        { width: 150, field: 'costCentreIsValid', displayName: 'Valid Cost Centre' },
        { width: 150, field: 'supplierIsValid', displayName: 'Valid Supplier' },
    ];
</code>```

This works fine but I want to reduce the code duplication by having a helper function that will return the cell template. Something like:

```<code>    function GetCellTemplate(fieldName, isValid)
{
    var template = `<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[fieldName]" />
                                    <span data-bind=\"visible: !$parent.selected(),
                                        text: $parent.entity[fieldName],
                                        css: isValid === 'True' ? \'passed-validation\' : \'failed-validation\'">
                                    </span>
                                </div>`;

    switch(expression) {
        case 'account':
            return template
            break;
        default:

    }
}
</code>```

This could be called by:

```<code>var accountEditTemplate = GetCellTemplate('account', $parent.entity.accountIsValid());
</code>```

My problem is when I try this I get ReferenceError:$parent is not defined

What's the best way to solve this copy & paste code growth - I will the same kind of functionality for many fields?

Code updated as per Jason's suggestion - not yet working

```<code>function GetCellTemplate(fieldName, validationFieldName) {
    var template = `<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[{fieldName}]\" />
                    <span data-bind=\"visible: !$parent.selected(),
                        text: $parent.entity[{fieldName}],
                        css: $parent.entity.{validationFieldName} === 'True' ? \'passed-validation\' : \'failed-validation\'\">
                    </span>
                </div>`;
    }

var editBatchVm = function () {
    var self = this;
    var $loadingIndicator = $('#loading-indicator');

    // Properties
    self.recs = ko.observableArray([]);
    self.selected = ko.observableArray();

    var accountEditTemplate = GetCellTemplate('account', 'accountIsValid');
    var costCentreEditTemplate = GetCellTemplate('costCentre', 'costCentreIsValid');
    var supplierEditTemplate = GetCellTemplate('supplier', 'supplierIsValid');

    self.columnDefs = [
        { width: 100, field: 'supplierNo', displayName: 'Supplier No', cellTemplate: supplierEditTemplate },
        { width: 150, field: 'invoiceNo', displayName: 'Invoice No' },
        { width: 150, field: 'costCentre', displayName: 'Cost Centre (Dim1)', cellTemplate: costCentreEditTemplate },
        { width: 200, field: 'glAccount', displayName: 'GL Account (Account)', cellTemplate: accountEditTemplate },
        { width: 100, field: 'amount', displayName: 'Amount' },
        { width: 300, field: 'invoiceDesc', displayName: 'Invoice Description' },
        { width: 150, field: 'accountIsValid', displayName: 'Valid Account' },
        { width: 150, field: 'costCentreIsValid', displayName: 'Valid Cost Centre' },
        { width: 150, field: 'supplierIsValid', displayName: 'Valid Supplier' },
    ];
</code>```

答:
Unless I'm mistaken you're just building a string that will later get executed as a template so there's no need to pass in the actual validation object during template construction, you just need the string that represents the validation object. The template itself can reference the $parent context later when it's executed.

```<code>var accountEditTemplate = GetCellTemplate('account', 'accountIsValid');
</code>```

...

```<code>function GetCellTemplate(fieldName, validationFieldName) {
    var template = "<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[" + fieldName + "]\" />" +
                   "    <span data-bind=\"visible: !$parent.selected()," +
                   "        text: $parent.entity[" + fieldName + "]," +
                   "        css: $parent.entity." + validationFieldName + " === 'True' ? \'passed-validation\' : \'failed-validation\'\">" +
                   "    </span>" +
                   "</div>";
    ...
}
</code>```

Body:
A beginner level javascript question...

I need to define a cell template for my KOGrid that is dependent on values in my VM. I want text to be displayed green if an associated field is True else display in red.

I have the following cell templates:

var accountEditTemplate = `
<input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[$data.field]" />

`;

    var costCentreEditTemplate = `
<input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[$data.field]" />

`;

These get used in my columnDefs as follows

self.columnDefs = [
        { width: 100, field: 'supplierNo', displayName: 'Supplier No', cellTemplate: supplierEditTemplate },
        { width: 150, field: 'invoiceNo', displayName: 'Invoice No' },
        { width: 150, field: 'costCentre', displayName: 'Cost Centre (Dim1)', cellTemplate: costCentreEditTemplate },
        { width: 200, field: 'glAccount', displayName: 'GL Account (Account)', cellTemplate: accountEditTemplate },
        { width: 100, field: 'amount', displayName: 'Amount' },
        { width: 300, field: 'invoiceDesc', displayName: 'Invoice Description' },
        { width: 150, field: 'accountIsValid', displayName: 'Valid Account' },
        { width: 150, field: 'costCentreIsValid', displayName: 'Valid Cost Centre' },
        { width: 150, field: 'supplierIsValid', displayName: 'Valid Supplier' },
    ];

This works fine but I want to reduce the code duplication by having a helper function that will return the cell template. Something like:

    function GetCellTemplate(fieldName, isValid)
{
    var template = `
<input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[fieldName]" />

`;

    switch(expression) {
        case 'account':
            return template
            break;
        default:

    }
}

This could be called by:

var accountEditTemplate = GetCellTemplate('account', $parent.entity.accountIsValid());

My problem is when I try this I get ReferenceError:$parent is not defined

What's the best way to solve this copy & paste code growth - I will the same kind of functionality for many fields?

Code updated as per Jason's suggestion - not yet working

function GetCellTemplate(fieldName, validationFieldName) {
    var template = `
<input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[{fieldName}]\" />

`;
    }

var editBatchVm = function () {
    var self = this;
    var $loadingIndicator = $('#loading-indicator');

    // Properties
    self.recs = ko.observableArray([]);
    self.selected = ko.observableArray();

    var accountEditTemplate = GetCellTemplate('account', 'accountIsValid');
    var costCentreEditTemplate = GetCellTemplate('costCentre', 'costCentreIsValid');
    var supplierEditTemplate = GetCellTemplate('supplier', 'supplierIsValid');

    self.columnDefs = [
        { width: 100, field: 'supplierNo', displayName: 'Supplier No', cellTemplate: supplierEditTemplate },
        { width: 150, field: 'invoiceNo', displayName: 'Invoice No' },
        { width: 150, field: 'costCentre', displayName: 'Cost Centre (Dim1)', cellTemplate: costCentreEditTemplate },
        { width: 200, field: 'glAccount', displayName: 'GL Account (Account)', cellTemplate: accountEditTemplate },
        { width: 100, field: 'amount', displayName: 'Amount' },
        { width: 300, field: 'invoiceDesc', displayName: 'Invoice Description' },
        { width: 150, field: 'accountIsValid', displayName: 'Valid Account' },
        { width: 150, field: 'costCentreIsValid', displayName: 'Valid Cost Centre' },
        { width: 150, field: 'supplierIsValid', displayName: 'Valid Supplier' },
    ];

Body:
Unless I'm mistaken you're just building a string that will later get executed as a template so there's no need to pass in the actual validation object during template construction, you just need the string that represents the validation object. The template itself can reference the $parent context later when it's executed.

var accountEditTemplate = GetCellTemplate('account', 'accountIsValid');

...

function GetCellTemplate(fieldName, validationFieldName) {
    var template = "<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[" + fieldName + "]\" />" +
                   "    <span data-bind=\"visible: !$parent.selected()," +
                   "        text: $parent.entity[" + fieldName + "]," +
                   "        css: $parent.entity." + validationFieldName + " === 'True' ? \'passed-validation\' : \'failed-validation\'\">" +
                   "    </span>" +
                   "</div>";
    ...
}


问:
angularjs - passing objects between components
I am working on an AngularJS/Ui-router project. I have two states:

state1

state2 (a sub-state of state1)

States code:

```<code>app.config(function($stateProvider){
  $stateProvider.state('state1', {
    url : '/state1',
    component : 'state1cpt',
    resolve : {
      state1data : function(){
        return {'x':1, 'y':2, 'z':3};
      }
    }
  });
  $stateProvider.state('state1.state2', {
    url : '/state2',
    component : 'state2cpt'
  });
});
</code>```

Each state has a component:

```<code>app.component('state1cpt', {
  bindings : {
    state1data : '<'
  },
  templateUrl : 'state1.html'
});

app.component('state2cpt', {
   templateUrl : 'state2.html'
});
</code>```

And the views:

index.html

```<code><a ui-sref="state1">State1</a>
<ui-view></ui-view>
</code>```

state1.html

```<code><h2>State1 x: {{$ctrl.state1data.x}}</h2>
<a ui-sref="state1.state2">State2</a>
<ui-view></ui-view>
</code>```

state2.html

```<code><h2>State2</h2>
</code>```

How can I pass the state1data object to the state2? And what is the better way to do it? (In resolve of state2, or in controller of state2?)

A running plunker: http://plnkr.co/edit/HDt0f4wzjyUVQ7lEI9YB?p=preview

答:
Just use a binding in component definition - still the resolved state1data from parent state will be available in all child states.

```<code>app.component('state2cpt', {
  bindings : {
    state1data : '<'
  },
  templateUrl : 'state2.html'
});
</code>```

state2.html

```<code><h2>State2</h2>
```{{$ctrl.state1data | json}}```
</code>```

or if you dont want to use binding - you can inject state1data in state2cpt controller

Body:
I am working on an AngularJS/Ui-router project. I have two states:

state1

state2 (a sub-state of state1)

States code:

app.config(function($stateProvider){
  $stateProvider.state('state1', {
    url : '/state1',
    component : 'state1cpt',
    resolve : {
      state1data : function(){
        return {'x':1, 'y':2, 'z':3};
      }
    }
  });
  $stateProvider.state('state1.state2', {
    url : '/state2',
    component : 'state2cpt'
  });
});

Each state has a component:

app.component('state1cpt', {
  bindings : {
    state1data : '<'
  },
  templateUrl : 'state1.html'
});

app.component('state2cpt', {
   templateUrl : 'state2.html'
});

And the views:

index.html

State1
<ui-view></ui-view>

state1.html

State1 x: {{$ctrl.state1data.x}}

State2
<ui-view></ui-view>

state2.html

State2

How can I pass the state1data object to the state2? And what is the better way to do it? (In resolve of state2, or in controller of state2?)

A running plunker: http://plnkr.co/edit/HDt0f4wzjyUVQ7lEI9YB?p=preview

Body:
Just use a binding in component definition - still the resolved state1data from parent state will be available in all child states.

app.component('state2cpt', {
  bindings : {
    state1data : '<'
  },
  templateUrl : 'state2.html'
});

state2.html

<h2>State2</h2>
<pre>{{$ctrl.state1data | json}}</pre>

or if you dont want to use binding - you can inject state1data in state2cpt controller


问:
How do I set the namespace URI in c#?
Im using a namespace in my xml (I need to use this for xsd validation purposes). Because of this my xpath is no longer working.

I have the code:

```<code>XmlDocument doc = new XmlDocument();
doc.Load(newXmlFilePath);
</code>```

And the XML:

```<code><?xml version="1.0" encoding="UTF-8"?>
<video xmlns="UploadXSD">
  <title>
    A vid with Pete
  </title>
  <description>
  Petes vid
  </description>
  <contributor>
    Pete
  </contributor>
  <subject>
    Cat 2
  </subject>
</video>
</code>```

But my xpath doesnt select the node. I tried to set the namespace using:

```<code>doc.NamespaceUR = "x";
</code>```

However its a get only accessor. Any ideas?

答:
```<code>XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
nsMgr.AddNamespace("vid", "UploadXSD");
</code>```

Note that you need to use this with your query. For example:

```<code>doc.SelectSingleNode("/vid:video/vid:subject", nsMgr);
</code>```

As otherwise the SelectSingleNode won't know to operate in the context of that manager.

Title: How do I set the namespace URI in c#?

Body:
Im using a namespace in my xml (I need to use this for xsd validation purposes). Because of this my xpath is no longer working.

I have the code:

XmlDocument doc = new XmlDocument();
doc.Load(newXmlFilePath);

And the XML:

<?xml version="1.0" encoding="UTF-8"?>
<video xmlns="UploadXSD">
  <title>
    A vid with Pete
  </title>
  <description>
  Petes vid
  </description>
  <contributor>
    Pete
  </contributor>
  <subject>
    Cat 2
  </subject>
</video>

But my xpath doesnt select the node. I tried to set the namespace using:

doc.NamespaceUR = "x";

However its a get only accessor. Any ideas?

Body:
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
nsMgr.AddNamespace("vid", "UploadXSD");

Note that you need to use this with your query. For example:

doc.SelectSingleNode("/vid:video/vid:subject", nsMgr);

As otherwise the SelectSingleNode won't know to operate in the context of that manager.


问:
How to avoid duplicates populating array with async service
I have a component that fetches content from a service to process it. The thing is I can have multiple calls to this function, which results in duplicates on my array. I the following workaround:

    getOptions(): Observable<PickQuality[]> {
    console.log("MY LENGTH: ", this.options.length) // <=== Always returns 0 because the callback hasn't run yet
    if(this.options.length == 0) {
        this.championService.getChampions()
            .subscribe(champions => {
                champions.forEach(champion => this.options.push(new PickQuality(champion, 0)));
                this.reevaluate();
                this.optionsSubject.next(this.options);
            });

        return this.optionsSubject.asObservable();
    }
    else
        return Observable.of(this.options);
}
```

<p>and it didn't work, and then I tried the following trick inside the callback (where the <code>this.options.length</code> is correctly recognized):</p>

<pre class="lang-ts prettyprint-override"><code>                    if(this.options.length != 0) return; // <=== Looks bad!
</code>```

which actually worked but seemed extremely inefficient to me, since the call to my service is still executed. How can I fix this?

答:
Check for duplicates before pushing them.

this.championService.getChampions()
.subscribe(champions => {
    champions.forEach(champion => {
       if (champions.indexOf(champion) == -1)
          this.options.push(new PickQuality(champion, 0));
    });
    this.reevaluate();
    this.optionsSubject.next(this.options);
});
```

Body:
I have a component that fetches content from a service to process it. The thing is I can have multiple calls to this function, which results in duplicates on my array. I the following workaround:

    getOptions(): Observable<PickQuality[]> {
    console.log("MY LENGTH: ", this.options.length) // <=== Always returns 0 because the callback hasn't run yet
    if(this.options.length == 0) {
        this.championService.getChampions()
            .subscribe(champions => {
                champions.forEach(champion => this.options.push(new PickQuality(champion, 0)));
                this.reevaluate();
                this.optionsSubject.next(this.options);
            });

        return this.optionsSubject.asObservable();
    }
    else
        return Observable.of(this.options);
}

and it didn't work, and then I tried the following trick inside the callback (where the this.options.length is correctly recognized):

                    if(this.options.length != 0) return; // <=== Looks bad!

which actually worked but seemed extremely inefficient to me, since the call to my service is still executed. How can I fix this?