问:
How to check for # of lines using jQuery
Example: a div with width of 30px with the words "this is text".  Let's say that, since the width is narrow, it renders on the page like this:

this

is

text

(3 lines).  Is there a way in jQuery to tell how many lines it takes to render to the page?  For example, something like, $("#container").lineCount().

Business purpose: if my content exceeds a certain number of lines, I want to manipulate it so that a scroll bar does not appear, but I also have a fixed height, so I don't want to mess with overflow css prop.

Thanks!

答:
This is tricky but can be done, even if there is no specified line-height or other style. It does involve a bunch of moving parts.

First, build a "sacrificial" container
. Fill it with a known number of lines of text, one character each, and position it far off-screen:

```<code>// calculate height per line
$calcdiv = $('<div/>').css({
  width: '50px',
  position: 'absolute', // don't affect layout
  left: '-2000px' // position far off=screen
}).html('A<br />B<br />C<br />D<br />E'); // add five lines

$('body').append( $calcdiv ); // make the browser render it

var lineHeight = $calcdiv.height()/5; // average height per line
</code>```

Now we know the approximate height of a line, in pixels, as rendered by this browser. We turn our attention to the box to be measured:

```<code>$origDiv = $('div#div_to_measure');
$measureDiv = $origDiv.clone(); // clone it
$measureDiv.css({
  position: 'absolute',
  left: '-1000px', // position far off-screen
  height: 'auto' // let it grow to its natural full height
});
$('body').append( $measurediv ); // add it to the DOM, browser will render it
</code>```

...and now we know the approximate number of lines in the box if allowed to attain its natural dimensions as rendered by the browser:

```<code>var numLines = $measureDiv.height() / lineHeight;
</code>```

We have to clone() because the original box to be measured may have its height restricted by the current page styles and layout.

Now some cleanup:

```<code>$calcdiv.remove();
$measureDiv.remove();
</code>```

Here's an example: http://jsfiddle.net/redler/FuWue/

ContentLicense: CC BY-SA 2.5

Body:
This is tricky but can be done, even if there is no specified line-height or other style. It does involve a bunch of moving parts.

First, build a "sacrificial" container <div>. Fill it with a known number of lines of text, one character each, and position it far off-screen:

// calculate height per line
$calcdiv = $('<div/>').css({
  width: '50px',
  position: 'absolute', // don't affect layout
  left: '-2000px' // position far off=screen
}).html('A<br />B<br />C<br />D<br />E'); // add five lines

$('body').append( $calcdiv ); // make the browser render it

var lineHeight = $calcdiv.height()/5; // average height per line

Now we know the approximate height of a line, in pixels, as rendered by this browser. We turn our attention to the box to be measured:

$origDiv = $('div#div_to_measure');
$measureDiv = $origDiv.clone(); // clone it
$measureDiv.css({
  position: 'absolute',
  left: '-1000px', // position far off-screen
  height: 'auto' // let it grow to its natural full height
});
$('body').append( $measurediv ); // add it to the DOM, browser will render it

...and now we know the approximate number of lines in the box if allowed to attain its natural dimensions as rendered by the browser:

var numLines = $measureDiv.height() / lineHeight;

We have to clone() because the original box to be measured may have its height restricted by the current page styles and layout.

Now some cleanup:

$calcdiv.remove();
$measureDiv.remove();

Here's an example: http://jsfiddle.net/redler/FuWue/


来源: stackexchange

问:
How to know once a dynamically added script is parsed/loaded/executed?
I am trying to dynamically load a JavaScript file and, once it is loaded, run a function that is inside the file.  In my main HTML, I basically have:

```<code>function load_javascript(js_file)
{
    function load_js_callback(example)
    {
        console.log("function " + function_in_js_file + " is " + typeof(function_name));
        if (typeof(function_in_js_file) == "undefined")
        {
            window.setTimeout(load_js_callback(example), 500);
            return false;
        }
        function_in_js_file(example);
    }

    var jstag = document.createElement("script");
    document.head.appendChild(jstag);

    // Browsers:
    jstag.onload=load_js_callback("example");
    // Internet Explorer:
    jstag.onreadystatechange = function() {
        if (this.readyState == 'complete') {
            load_js_callback("example");
        }
    }
    jstag.setAttribute('src',js_file);
}

load_javascript("/js/example.js");
</code>```

From what I can find on the internet (https://stackoverflow.com/a/3248500 and https://stackoverflow.com/a/16231055) this should work, but the jstag.onload runs before the function_in_js_file is defined, so I need the window.setTimeout to check again until the function is defined.

Ideally, I would like to get rid of that timeout.  Is there any way to know when the file has been completed loaded/parsed/executed (I'm not sure which is the right term) and the function is defined, ideally without changing the dynamic file?  I have also tried putting the document.head.appendChild(jstag); after the jstag.setAttribute, but with the same results.

答:
Consider using DOMContentLoaded js event</p>

```<code>document.addEventListener('DOMContentLoader', function () {
    load_javascript("/js/example.js"); // Or what else you want to do
    // HERE I'm confident that my webpage is loaded and my js files too.
})
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am trying to dynamically load a JavaScript file and, once it is loaded, run a function that is inside the file.  In my main HTML, I basically have:

function load_javascript(js_file)
{
    function load_js_callback(example)
    {
        console.log("function " + function_in_js_file + " is " + typeof(function_name));
        if (typeof(function_in_js_file) == "undefined")
        {
            window.setTimeout(load_js_callback(example), 500);
            return false;
        }
        function_in_js_file(example);
    }

    var jstag = document.createElement("script");
    document.head.appendChild(jstag);

    // Browsers:
    jstag.onload=load_js_callback("example");
    // Internet Explorer:
    jstag.onreadystatechange = function() {
        if (this.readyState == 'complete') {
            load_js_callback("example");
        }
    }
    jstag.setAttribute('src',js_file);
}

load_javascript("/js/example.js");

From what I can find on the internet (https://stackoverflow.com/a/3248500 and https://stackoverflow.com/a/16231055) this should work, but the jstag.onload runs before the function_in_js_file is defined, so I need the window.setTimeout to check again until the function is defined.

Ideally, I would like to get rid of that timeout.  Is there any way to know when the file has been completed loaded/parsed/executed (I'm not sure which is the right term) and the function is defined, ideally without changing the dynamic file?  I have also tried putting the document.head.appendChild(jstag); after the jstag.setAttribute, but with the same results.

Body:
Consider using DOMContentLoaded js event

document.addEventListener('DOMContentLoader', function () {
    load_javascript("/js/example.js"); // Or what else you want to do
    // HERE I'm confident that my webpage is loaded and my js files too.
})


问:
Progress Bar not showing in screen but showing in debugger
I am adding a Progress Bar when the user does a search query, and it will not show up in the screen. Here are the snippets:

```<code>    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button searchButton = (Button) findViewById(R.id.searchButton);
        setContentView(R.layout.activity_main); //main layout, which has a child layout called resultsLayout
        searchButton.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            EditText searchString = (EditText) findViewById(R.id.searchString);
            search(searchString.getText().toString());
        }
    });

    protected void search(String searchString){
        LinearLayout resultLayout = ((LinearLayout)    findViewById(R.id.resultsLayout));
        resultLayout.addView(DisplayResults.getLoadBar(getApplicationContext()));
        //do search
        resultLayout.removeAllViews();
    }

    public static ProgressBar getLoadBar(Context context){
        ProgressBar loadBar = new ProgressBar(context);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        loadBar.setLayoutParams(params);
        loadBar.setVisibility(View.VISIBLE);
        return loadBar;
    }
</code>```

I know some of it might not be needed, like the setVisibility right when creating, but I have tried several things and it not works. Perhaps there wasn't enough time to show up the bar?(It takes about 1.5sec for the search)

I have also debugged the application, and it shows the ProgressBar as a child of the layout, but I still cannot see it in the screen.

答: add setContentView(resultLayout); at the end of search() method

Body:
I am adding a Progress Bar when the user does a search query, and it will not show up in the screen. Here are the snippets:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button searchButton = (Button) findViewById(R.id.searchButton);
        setContentView(R.layout.activity_main); //main layout, which has a child layout called resultsLayout
        searchButton.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            EditText searchString = (EditText) findViewById(R.id.searchString);
            search(searchString.getText().toString());
        }
    });

    protected void search(String searchString){
        LinearLayout resultLayout = ((LinearLayout)    findViewById(R.id.resultsLayout));
        resultLayout.addView(DisplayResults.getLoadBar(getApplicationContext()));
        //do search
        resultLayout.removeAllViews();
    }

    public static ProgressBar getLoadBar(Context context){
        ProgressBar loadBar = new ProgressBar(context);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        loadBar.setLayoutParams(params);
        loadBar.setVisibility(View.VISIBLE);
        return loadBar;
    }

I know some of it might not be needed, like the setVisibility right when creating, but I have tried several things and it not works. Perhaps there wasn't enough time to show up the bar?(It takes about 1.5sec for the search)

I have also debugged the application, and it shows the ProgressBar as a child of the layout, but I still cannot see it in the screen.


问:
Initialization and pushing data in array
First, I declare an array :

```<code>let arr = [];
</code>```

Hence, I fill this array in the following way :

```<code>(async function loop() {
        for(let i=timeStart; i<=timeEnd; i+=3600000)
        {
          await ExternDataProvider.getCountData(i, (i+3600000), localSearchFilters)
            .then(function(dataResult){
              arr.push(dataResult);
            })
            .catch(function(err){
            });
        }
      })();
</code>```

But, when I make a console.log of the variable "arr", I have the following result :

So why I dont have something like [2251,215] instead ?

答:
You have [2251,215]

But console shows it in a different way.

The 0 means value in 0th position.

The 1 means value in 1th position

Body:
First, I declare an array :

let arr = [];

Hence, I fill this array in the following way :

(async function loop() {
        for(let i=timeStart; i<=timeEnd; i+=3600000)
        {
          await ExternDataProvider.getCountData(i, (i+3600000), localSearchFilters)
            .then(function(dataResult){
              arr.push(dataResult);
            })
            .catch(function(err){
            });
        }
      })();

But, when I make a console.log of the variable "arr", I have the following result :

So why I dont have something like [2251,215] instead ?


问:
When submit button is Clicked on the final page I need a center display wording "Thank you for your time", and image of a green cheek mark included
I have finished making a survey page which is based purely on HTML and jQuery. Now the next part is when the submit button is clicked I need everything to become hidden and the only display should show is simple HTML code in bold wording "Thank you for you time" with image. </p>

<p>Here's my code so for... </p>

```<code>@foreach (var i in Model)
{

        if (i.Question_Type == "DROPDOWN")
        {

        <div class="container text-center">

            <div class="row idrow" data-questions="@counter">
                @{counter++;
                }

                <div id="question1" class="form-group">
                    <label class="lab text-center" for="form-group-select">
                        @i.Question_Order @Html.Raw(@i.Question)
                    </label>
                    @{ var works = "question" + counter.ToString();}
                    <select name="@works" class="form-control selects" id="form-group-select">
                        @for (int x = 1; x <= Convert.ToInt32(i.Question_SubType); x++)
                        {
                            var t = x - 1;
                            if (i.qOps != null)
                            {
                                <option> @i.qOps.options[t]</option>
                            }
                            else
                            {
                                <option> @x</option>

                            }
                        }
                    </select>
                </div>
            </div>

        </div>

        }

        if (i.Question_Type == "RADIO")
        {

        <div class="container">
            <div class="row idrow" data-questions="@counter">
                @{counter++;
                }
                <div class="form-group">
                    <label class="lab" for="questions">
                        @i.Question_Order @i.Question
                    </label>
                    <div class="row">
                        <div class="col-xs-12">
                            <div id="question1" class="radio-inline">
                                @for (int x = 1; x <= Convert.ToInt32(i.Question_SubType); x++)
                                {
                                    var t = x - 1;
                                    if (i.qOps != null)
                                    {
                                        <label class="radio-inline"><input type="radio" name="question"> @i.qOps.options[t]</label>
                                    }
                                    else
                                    {

                                        <label class="radio-inline"><input type="radio" min="0" max="@x" name="question"></label>

                                    }
                                }
                            </div>

                        </div>

                    </div>
                </div>

            </div>
        </div>

        }
        if (i.Question_Type == "CHECKBOX")
        {
        for (int y = 1; y <= Convert.ToInt32(i.Question_SubType); y++)
        {
        @*<div class="container">
                <div class="row">

                    <label>@y</label>   <input type="checkbox" name="question">

                </div>
            </div>*@
        }
        }

        }
       <div class="container ">
    <div class="azibsButtons">
        <button type="button" id="previous" class="btn btn-primary pull-left">Prev</button>

        <button type="button" id="next" class="btn btn-primary pull-right">Next</button>

        <button type="button" id="submit" onclick="Sendingitoff();" class="btn btn-primary pull-right">Submit</button>

    </div>

</div>
<div id="final">
    Thank you for your time

</div>

        <script>
            function formToJSON() {
                var form = {};
                $('.selects').each(function () {
                    var self = $(this);
                    var name = self.attr('name');
                    if (form[name]) {
                        form[name] = form[name] + ',' + self.val();
                    }
                    else {
                        form[name] = self.val();
                    }
                });

                return form;
            }

            function Sendingitoff() {
               // debugger;
                var form = formToJSON();
                var look = JSON.stringify(form);

                $.ajax({
                    url: '@Url.Action("Answers", "GSSurvey")/' + '?username=@Request.QueryString["username"]' + '&receiverid=@Request.QueryString["receiverid"]' + '&id=@Request.QueryString["id"]',

                    type: 'POST',
                    contentType: "application/json",
                    dataType: 'json',
                    data: look,
                    success: function (data, textStatus, jqXHR) {

                    },
                    error: function (jqXHR, textStatus, errorThrown) {

                    }
                });

            }
            $(document).ready(function () {
                ShowTheelement(0);
                $("#previous").addClass('hidden');
                $("#submit").addClass('hidden');

                var dataVal = 0;

                $("#next").click(function () {
                    dataVal++;
                    $("#previous").removeClass('hidden');
                    dataVal == $(".idrow[data-questions]").length - 1 ? $(this).addClass('hidden') : $(this).removeClass('hidden');
                    ShowTheelement(dataVal);
                    if (dataVal == $(".idrow[data-questions]").length -1 ) {
                        $("#submit").removeClass('hidden');
                    }

                });

                $("#previous").click(function () {
                    dataVal--;
                    $("#next").removeClass('hidden');
                    dataVal == 0 ? $(this).addClass('hidden') : $(this).removeClass('hidden');
                    ShowTheelement(dataVal);
                    if (dataVal == $(".idrow[data-questions]").length - 2)
                        $("#submit").addClass('hidden');

                });
            });

            function ShowTheelement(dataVal) {
                $(".idrow").addClass('hidden');
                $(".idrow[data-questions='" + dataVal + "']").removeClass('hidden');

            }
        </script>
</code>```

答:
If I understood correctly you want to show the div with id final, in a way it takes up everything.
You could just make this div start hidden (give it the existing class hidden) and after form submission show it, overlapping above the rest (like a modal).

One way to do it would be:

Create a css class for the final div

```<code>.overlay {
 position:fixed;
 height: 100%;
 width: 100%;
 top: 0px;
 left: 0px;
}
</code>```

Hide it by default

```<code><div id="final" class="hidden"> Thank you for your time </div>
</code>```

Then, after the success of your ajax call:

```<code>success: function (data, textStatus, jqXHR) {
 /*do what you need with the data*/
 $("#final").addClass('overlay');
}
</code>```

Remember this will take up all of your screen so you should consider a timer to close it or a close button to hide it.

Body:
I have finished making a survey page which is based purely on HTML and jQuery. Now the next part is when the submit button is clicked I need everything to become hidden and the only display should show is simple HTML code in bold wording "Thank you for you time" with image.

Here's my code so for...

@foreach (var i in Model)
{

        if (i.Question_Type == "DROPDOWN")
        {

                @{counter++;
                }

                        @i.Question_Order @Html.Raw(@i.Question)

                    @{ var works = "question" + counter.ToString();}
                    <select name="@works" class="form-control selects" id="form-group-select">
                        @for (int x = 1; x <= Convert.ToInt32(i.Question_SubType); x++)
                        {
                            var t = x - 1;
                            if (i.qOps != null)
                            {
                                <option> @i.qOps.options[t]</option>
                            }
                            else
                            {
                                <option> @x</option>

                            }
                        }
                    </select>

        }

        if (i.Question_Type == "RADIO")
        {

                @{counter++;
                }

                        @i.Question_Order @i.Question

                                @for (int x = 1; x <= Convert.ToInt32(i.Question_SubType); x++)
                                {
                                    var t = x - 1;
                                    if (i.qOps != null)
                                    {
                                        <input type="radio" name="question"> @i.qOps.options[t]
                                    }
                                    else
                                    {

                                        <input type="radio" min="0" max="@x" name="question">

                                    }
                                }

        }
        if (i.Question_Type == "CHECKBOX")
        {
        for (int y = 1; y <= Convert.ToInt32(i.Question_SubType); y++)
        {
        @*

                    @y   <input type="checkbox" name="question">

*@
        }
        }

        }

        <button type="button" id="previous" class="btn btn-primary pull-left">Prev</button>

        <button type="button" id="next" class="btn btn-primary pull-right">Next</button>

        <button type="button" id="submit" onclick="Sendingitoff();" class="btn btn-primary pull-right">Submit</button>

    Thank you for your time

Body:
If I understood correctly you want to show the div with id final, in a way it takes up everything.
You could just make this div start hidden (give it the existing class hidden) and after form submission show it, overlapping above the rest (like a modal).

One way to do it would be:

Create a css class for the final div

.overlay {
 position:fixed;
 height: 100%;
 width: 100%;
 top: 0px;
 left: 0px;
}

Hide it by default

<div id="final" class="hidden"> Thank you for your time </div>

Then, after the success of your ajax call:

success: function (data, textStatus, jqXHR) {
 /*do what you need with the data*/
 $("#final").addClass('overlay');
}

Remember this will take up all of your screen so you should consider a timer to close it or a close button to hide it.


问:
TypeScript / Angular 2 creating a dynamic object deserializer
So I am coming from a background of C# where I can do things in a dynamic and reflective way and I am trying to apply that to a TypeScript class I am working on writing.
Some background, I am converting an application to a web app and the backend developer doesn't want to change the backend at all to accommodate Json very well. So he is going to be sending me back Json that looks like so:

```<code>{
 Columns: [
  {
   "ColumnName": "ClientPK",
   "Label": "Client",
   "DataType": "int",
   "Length": 0,
   "AllowNull": true,
   "Format": "",
   "IsReadOnly": true,
   "IsDateOnly": null
  }
 ],
 Rows:[
  0
 ]
}
</code>```

I am looking to write an Angular class that extends Response that will have a special method called JsonMinimal which will understand this data and return an object for me.

```<code>import { Response } from "@angular/http";

export class ServerSource
{
    SourceName: string;
    MoreItems: boolean;
    Error: string;
    ExtendedProperties: ExtendedProperty[];
    Columns: Column[];
}

export class ServerSourceResponse extends Response
{

    JsonMinimal() : any
    {

        return null; //Something that will be a blank any type that when returned I can perform `object as FinalObject` syntax
    }

}
</code>```

I know StackOverflow isn't for asking for complete solutions to problems so I am only asking what is one example taking this example data and creating a dynamic response that TypeScript isn't going to yell at me for. I don't know what to do here, this developer has thousands of server-side methods and all of them return strings, in the form of a JSON or XML output. I am basically looking for a way to take his column data and combine it with the proper row data and then have a bigger object that holds a bunch of these combined object.

A usage case here after that data has been mapped to a basic object would be something like this.
Example:

```<code>var data = result.JsonMinimal() as LoginResponse; <-- Which will map to this object correctly if all the data is there in a base object.

var pk = data.ClientPK.Value;
</code>```

答:
I'm not exactly sure I understand, but you may want to try a simple approach first. Angular's http get method returns an observable that can automatically map the response to an object or an array of objects. It is also powerful enough to perform some custom mapping/transformation. You may want to look at that first.

Here is an example:

```<code>getProducts(): Observable<IProduct[]> {
    return this._http.get(this._productUrl)
        .map((response: Response) => <IProduct[]> response.json())
        .do(data => console.log('All: ' +  JSON.stringify(data)))
        .catch(this.handleError);
}
</code>```

Here I'm mapping a json response to an array of Product objects I've defined with an IProduct interface. Since this is just a "lambda" type function, I could add any amount of code here to transform data.

Body:
So I am coming from a background of C# where I can do things in a dynamic and reflective way and I am trying to apply that to a TypeScript class I am working on writing.
Some background, I am converting an application to a web app and the backend developer doesn't want to change the backend at all to accommodate Json very well. So he is going to be sending me back Json that looks like so:

{
 Columns: [
  {
   "ColumnName": "ClientPK",
   "Label": "Client",
   "DataType": "int",
   "Length": 0,
   "AllowNull": true,
   "Format": "",
   "IsReadOnly": true,
   "IsDateOnly": null
  }
 ],
 Rows:[
  0
 ]
}

I am looking to write an Angular class that extends Response that will have a special method called JsonMinimal which will understand this data and return an object for me.

import { Response } from "@angular/http";

export class ServerSource
{
    SourceName: string;
    MoreItems: boolean;
    Error: string;
    ExtendedProperties: ExtendedProperty[];
    Columns: Column[];
}

export class ServerSourceResponse extends Response
{

    JsonMinimal() : any
    {

        return null; //Something that will be a blank any type that when returned I can perform `object as FinalObject` syntax
    }

}

I know StackOverflow isn't for asking for complete solutions to problems so I am only asking what is one example taking this example data and creating a dynamic response that TypeScript isn't going to yell at me for. I don't know what to do here, this developer has thousands of server-side methods and all of them return strings, in the form of a JSON or XML output. I am basically looking for a way to take his column data and combine it with the proper row data and then have a bigger object that holds a bunch of these combined object.

A usage case here after that data has been mapped to a basic object would be something like this.
Example:

var data = result.JsonMinimal() as LoginResponse; <-- Which will map to this object correctly if all the data is there in a base object.

var pk = data.ClientPK.Value;

Body:
I'm not exactly sure I understand, but you may want to try a simple approach first. Angular's http get method returns an observable that can automatically map the response to an object or an array of objects. It is also powerful enough to perform some custom mapping/transformation. You may want to look at that first.

Here is an example:

getProducts(): Observable<IProduct[]> {
    return this._http.get(this._productUrl)
        .map((response: Response) => <IProduct[]> response.json())
        .do(data => console.log('All: ' +  JSON.stringify(data)))
        .catch(this.handleError);
}

Here I'm mapping a json response to an array of Product objects I've defined with an IProduct interface. Since this is just a "lambda" type function, I could add any amount of code here to transform data.


问:
In a series of Meteor.call()'s within each other, the original call is returning early
I've made a Meteor.Method (let's call it the fullFlow) which itself calls a bunch of Meteor methods. My goal is to have the subsequent methods called asynchronously since the subsequent method requires the res of the previous method to do its work.

The problem is, the callback from the fullFlow is getting returned after the first method in the series it runs since the first method gets a return value (and then passes it to the next method, etc).

This is my issue: I want the fullFlow method to wait until the last method in the series is completed and return it's value to the callback of the fullFlow.

I'm assuming my structure is all wrong and that's why this is happening. I'd appreciate it if someone could help me out and either fix my flow or explain what I'm missing so I can fix it!

Here's the code:

```<code>Meteor.methods({
  step1(params) {
    // work with params
    return stuff
  },

  step2(params) {
    // work with params
    return stuff
  },

  step3(params3) {
    // work with params
    return stuff
  },

  fullFlow(params) {
    Meteor.call('step1', params, function (err, res) {
      if (err) {
        throw new Meteor.Error(err);
      } else {
        Meteor.call('step2', res, function (err, res) {
          if (err) {
            throw new Meteor.Error(err);
          } else {
            Meteor.call('step3', res, function (err, res) {
              if (err) {
                throw new Meteor.Error(err);
              } else {
                return res;
              }
            })
          }
        })
      }
    })
  }
})

function fullFlow() {
  Meteor.call('fullFlow', params, function (err, res) {
    if (err) {
      console.log(err)
    } else {
      console.log(res)
    }
  })
}

fullFlow();
</code>```

Now what's happening is that when step1's callback is called with the res, it's also calling the main callback of fullFlow. The weird part is the rest of the fullFlow method still continues to execute and functions as expected (ie it waits for the res of the previous method before going onto the next one and passes it through properly), but the general callback has been fired.

My problem is I need to have this fullFlow function running continuously. My goal was to wait for the function's callback to be called and then within that callback, call the function itself to start over. This will not work properly if the callback is called before the full series of methods are completed. Also I need the res from the last method called in the series to be returned to the fullFlow callback!

Any ideas?

答:
And just like that, I figured it out.

I wrapped everything inside the fullFlow method within a future. So the new syntax is:

```<code>var Future = Npm.require( 'fibers/future' );

fullFlow(params) {
  var future = new Future();

  Meteor.call('step1', params, function (err, res) {
    if (err) {
      throw new Meteor.Error(err);
    } else {
      Meteor.call('step2', res, function (err, res) {
        if (err) {
          throw new Meteor.Error(err);
        } else {
          Meteor.call('step3', res, function (err, res) {
            if (err) {
              throw new Meteor.Error(err);
            } else {
              return future.return(res);
            }
          })
        }
      })
    }
  })

  return future.wait();
}
</code>```

Now the whole thing doesn't callback until the last method is done and it successfully returns the last res to the callback of fullFlow.

This works but I am still unsure if this is a hacky way to solve bad structure. I'd rather have proper structure. If someone can correct the overall structure please tell me!

Body:
I've made a Meteor.Method (let's call it the fullFlow) which itself calls a bunch of Meteor methods. My goal is to have the subsequent methods called asynchronously since the subsequent method requires the res of the previous method to do its work.

The problem is, the callback from the fullFlow is getting returned after the first method in the series it runs since the first method gets a return value (and then passes it to the next method, etc).

This is my issue: I want the fullFlow method to wait until the last method in the series is completed and return it's value to the callback of the fullFlow.

I'm assuming my structure is all wrong and that's why this is happening. I'd appreciate it if someone could help me out and either fix my flow or explain what I'm missing so I can fix it!

Here's the code:

Meteor.methods({
  step1(params) {
    // work with params
    return stuff
  },

  step2(params) {
    // work with params
    return stuff
  },

  step3(params3) {
    // work with params
    return stuff
  },

  fullFlow(params) {
    Meteor.call('step1', params, function (err, res) {
      if (err) {
        throw new Meteor.Error(err);
      } else {
        Meteor.call('step2', res, function (err, res) {
          if (err) {
            throw new Meteor.Error(err);
          } else {
            Meteor.call('step3', res, function (err, res) {
              if (err) {
                throw new Meteor.Error(err);
              } else {
                return res;
              }
            })
          }
        })
      }
    })
  }
})

function fullFlow() {
  Meteor.call('fullFlow', params, function (err, res) {
    if (err) {
      console.log(err)
    } else {
      console.log(res)
    }
  })
}

fullFlow();

Now what's happening is that when step1's callback is called with the res, it's also calling the main callback of fullFlow. The weird part is the rest of the fullFlow method still continues to execute and functions as expected (ie it waits for the res of the previous method before going onto the next one and passes it through properly), but the general callback has been fired.

My problem is I need to have this fullFlow function running continuously. My goal was to wait for the function's callback to be called and then within that callback, call the function itself to start over. This will not work properly if the callback is called before the full series of methods are completed. Also I need the res from the last method called in the series to be returned to the fullFlow callback!

Any ideas?

Body:
And just like that, I figured it out.

I wrapped everything inside the fullFlow method within a future. So the new syntax is:

var Future = Npm.require( 'fibers/future' );

fullFlow(params) {
  var future = new Future();

  Meteor.call('step1', params, function (err, res) {
    if (err) {
      throw new Meteor.Error(err);
    } else {
      Meteor.call('step2', res, function (err, res) {
        if (err) {
          throw new Meteor.Error(err);
        } else {
          Meteor.call('step3', res, function (err, res) {
            if (err) {
              throw new Meteor.Error(err);
            } else {
              return future.return(res);
            }
          })
        }
      })
    }
  })

  return future.wait();
}

Now the whole thing doesn't callback until the last method is done and it successfully returns the last res to the callback of fullFlow.

This works but I am still unsure if this is a hacky way to solve bad structure. I'd rather have proper structure. If someone can correct the overall structure please tell me!


问:
Sed only with specific place
For example;

I'd love to replace /test src path only within  tag.

However
test
 should not be touched.

```<code>$ cat test.html
<img src="/test" width="18" alt="" /><br>
<p>test</p>
</code>```

For now I could execute something like;

```<code>sed -i '/test'|/hoge|g' test.html
</code>```

However it changes the word globally.

答:
sed '/<img/s|/test|/hoge|g' test.html would work for one line <img tags

Sed allows the s///g replacement to be prefixed with another /PATTERN/ to restrict the replacement to lines matching PATTERN.

But you should really use an xml parser to be safe.

Title: Sed only with specific place

Body:
For example;

I'd love to replace /test src path only within  tag.

However
test
 should not be touched.

$ cat test.html

test

For now I could execute something like;

sed -i '/test'|/hoge|g' test.html

However it changes the word globally.


问:
SQL Query to display 2 columns in correct order
Check my SQL Query in this Fiddle: sql fiddle

What I want from the SQL Query?

As you can see, I insert 3 things in recommendations table.

recommendations_tmdb_id

recommendations_title

recommendations_vote_average

I use recommendations_tmdb_id to connect the recommendations table to `tmdb_movies table

I want to display recommendations_title and recommendations_vote_average.

In my original code: This is how i am displaying data:

```<code>The Dark Knight Rises - 7.5
Batman Begins - 7.5
Iron Man - 7.3
The Lord of the Rings: The Return of the King - 8.1
</code>```

etc..

But for the sake of simplicity, i do not want to include full code, just the required code.

So in the SQL fiddle, this is how the data echo

Problems with this code:

Problem number one:

Look at the code carefully. The second recommendations_vote_average number is 7.5 and the second recommendations_title movie name is Batman Begins

So, it means my code shows Batman Begins movie has an vote_average rating of 7.5, which is false. I insert the rating of Batman Begins as 7.3 not 7.5.

It is showing rating of some other movie. So that means, in wrong order.

Problem number 2:

It shows only 6 vote_average results, not 10. I inserted 10 records.
Why it show only 6 records not 10? Because of DISTINCT in my group_concat line.

What if I removeDISTINCT? Then, it will show rating of 7.5 to all movies.

So, how do i fix this problem?

Expected Result:

```<code>       recommendations_vote_average                           recommendations_title

7.5, 7.5, 7.3, 8.1, 8, 7.9, 7.9, 8, 6.6, 6.6          The Dark Knight Rises,Batman Begins,Iron Man,The Lord of the Rings: The Return of the King,The Lord of the Rings: The The Fellowship of the Ring,The Lord of the Rings: The Two Towers,The Matrix,Inception,Iron Man 2,Captain America: The First Avenger
</code>```

SQL Fiddle Full Code

```<code>CREATE TABLE tmdb_movies (
  tmdb_id INTEGER NOT NULL PRIMARY KEY,
  movie_title TEXT NOT NULL
);

INSERT INTO tmdb_movies (tmdb_id, movie_title) VALUES
(1, 'The Dark Knight');

CREATE TABLE recommendations (
  recommendations_tmdb_id INTEGER NOT NULL,
  recommendations_title TEXT NOT NULL,
  recommendations_vote_average TEXT NOT NULL
);

INSERT INTO recommendations (recommendations_tmdb_id, recommendations_title, recommendations_vote_average) VALUES
(1, 'The Dark Knight Rises', '7.5'),
(1, 'Batman Begins', '7.5'),
(1, 'Iron Man', '7.3'),
(1, 'The Lord of the Rings: The Return of the King', '8.1'),
(1, 'The Lord of the Rings: The The Fellowship of the Ring', '8'),
(1, 'The Lord of the Rings: The Two Towers', '7.9'),
(1, 'The Matrix', '7.9'),
(1, 'Inception', '8'),
(1, 'Iron Man 2', '6.6'),
(1, 'Captain America: The First Avenger', '6.6');

SELECT tmdb_movies.movie_title
,GROUP_CONCAT(DISTINCT recommendations.recommendations_vote_average) as recommendations_vote_average
,GROUP_CONCAT(DISTINCT recommendations.recommendations_title) as recommendations_title
FROM tmdb_movies

LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id

Where tmdb_movies.tmdb_id=1

GROUP BY tmdb_movies.movie_title
</code>```

答:
Drop DSTINCT from GROUP_CONCAT()

```<code>CREATE TABLE tmdb_movies (
  tmdb_id INTEGER NOT NULL PRIMARY KEY,
  movie_title TEXT NOT NULL
);

INSERT INTO tmdb_movies (tmdb_id, movie_title) VALUES
(1, 'The Dark Knight');

CREATE TABLE recommendations (
  recommendations_tmdb_id INTEGER NOT NULL,
  recommendations_title TEXT NOT NULL,
  recommendations_vote_average TEXT NOT NULL
);

INSERT INTO recommendations (recommendations_tmdb_id, recommendations_title, recommendations_vote_average) VALUES
(1, 'The Dark Knight Rises', '7.5'),
(1, 'Batman Begins', '7.5'),
(1, 'Iron Man', '7.3'),
(1, 'The Lord of the Rings: The Return of the King', '8.1'),
(1, 'The Lord of the Rings: The The Fellowship of the Ring', '8'),
(1, 'The Lord of the Rings: The Two Towers', '7.9'),
(1, 'The Matrix', '7.9'),
(1, 'Inception', '8'),
(1, 'Iron Man 2', '6.6'),
(1, 'Captain America: The First Avenger', '6.6');

SELECT tmdb_movies.movie_title
,GROUP_CONCAT(recommendations.recommendations_vote_average) as recommendations_vote_average
,GROUP_CONCAT(recommendations.recommendations_title) as recommendations_title
FROM tmdb_movies ;
</code>```

Returns

```<code>    movie_title recommendations_vote_average    recommendations_title
1   The Dark Knight 7.5,7.5,7.3,8.1,8,7.9,7.9,8,6.6,6.6 The Dark Knight Rises,Batman Begins,Iron Man,The Lord of the Rings: The Return of the King,The Lord of the Rings: The The Fellowship of the Ring,The Lord of the Rings: The Two Towers,The Matrix,Inception,Iron Man 2,Captain America: The First Avenger
</code>```

http://rextester.com/NNJA85394

Body:
Check my SQL Query in this Fiddle: sql fiddle

What I want from the SQL Query?

As you can see, I insert 3 things in recommendations table.

recommendations_tmdb_id

recommendations_title

recommendations_vote_average

I use recommendations_tmdb_id to connect the recommendations table to `tmdb_movies table

I want to display recommendations_title and recommendations_vote_average.

In my original code: This is how i am displaying data:

The Dark Knight Rises - 7.5
Batman Begins - 7.5
Iron Man - 7.3
The Lord of the Rings: The Return of the King - 8.1

etc..

But for the sake of simplicity, i do not want to include full code, just the required code.

So in the SQL fiddle, this is how the data echo

Problems with this code:

Problem number one:

Look at the code carefully. The second recommendations_vote_average number is 7.5 and the second recommendations_title movie name is Batman Begins

So, it means my code shows Batman Begins movie has an vote_average rating of 7.5, which is false. I insert the rating of Batman Begins as 7.3 not 7.5.

It is showing rating of some other movie. So that means, in wrong order.

Problem number 2:

It shows only 6 vote_average results, not 10. I inserted 10 records.
Why it show only 6 records not 10? Because of DISTINCT in my group_concat line.

What if I removeDISTINCT? Then, it will show rating of 7.5 to all movies.

So, how do i fix this problem?

Expected Result:

       recommendations_vote_average                           recommendations_title

7.5, 7.5, 7.3, 8.1, 8, 7.9, 7.9, 8, 6.6, 6.6          The Dark Knight Rises,Batman Begins,Iron Man,The Lord of the Rings: The Return of the King,The Lord of the Rings: The The Fellowship of the Ring,The Lord of the Rings: The Two Towers,The Matrix,Inception,Iron Man 2,Captain America: The First Avenger

SQL Fiddle Full Code

CREATE TABLE tmdb_movies (
  tmdb_id INTEGER NOT NULL PRIMARY KEY,
  movie_title TEXT NOT NULL
);

INSERT INTO tmdb_movies (tmdb_id, movie_title) VALUES
(1, 'The Dark Knight');

CREATE TABLE recommendations (
  recommendations_tmdb_id INTEGER NOT NULL,
  recommendations_title TEXT NOT NULL,
  recommendations_vote_average TEXT NOT NULL
);

INSERT INTO recommendations (recommendations_tmdb_id, recommendations_title, recommendations_vote_average) VALUES
(1, 'The Dark Knight Rises', '7.5'),
(1, 'Batman Begins', '7.5'),
(1, 'Iron Man', '7.3'),
(1, 'The Lord of the Rings: The Return of the King', '8.1'),
(1, 'The Lord of the Rings: The The Fellowship of the Ring', '8'),
(1, 'The Lord of the Rings: The Two Towers', '7.9'),
(1, 'The Matrix', '7.9'),
(1, 'Inception', '8'),
(1, 'Iron Man 2', '6.6'),
(1, 'Captain America: The First Avenger', '6.6');

SELECT tmdb_movies.movie_title
,GROUP_CONCAT(DISTINCT recommendations.recommendations_vote_average) as recommendations_vote_average
,GROUP_CONCAT(DISTINCT recommendations.recommendations_title) as recommendations_title
FROM tmdb_movies

LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id

Where tmdb_movies.tmdb_id=1

GROUP BY tmdb_movies.movie_title

Body:
Drop DSTINCT from GROUP_CONCAT()

CREATE TABLE tmdb_movies (
  tmdb_id INTEGER NOT NULL PRIMARY KEY,
  movie_title TEXT NOT NULL
);

INSERT INTO tmdb_movies (tmdb_id, movie_title) VALUES
(1, 'The Dark Knight');

CREATE TABLE recommendations (
  recommendations_tmdb_id INTEGER NOT NULL,
  recommendations_title TEXT NOT NULL,
  recommendations_vote_average TEXT NOT NULL
);

INSERT INTO recommendations (recommendations_tmdb_id, recommendations_title, recommendations_vote_average) VALUES
(1, 'The Dark Knight Rises', '7.5'),
(1, 'Batman Begins', '7.5'),
(1, 'Iron Man', '7.3'),
(1, 'The Lord of the Rings: The Return of the King', '8.1'),
(1, 'The Lord of the Rings: The The Fellowship of the Ring', '8'),
(1, 'The Lord of the Rings: The Two Towers', '7.9'),
(1, 'The Matrix', '7.9'),
(1, 'Inception', '8'),
(1, 'Iron Man 2', '6.6'),
(1, 'Captain America: The First Avenger', '6.6');

SELECT tmdb_movies.movie_title
,GROUP_CONCAT(recommendations.recommendations_vote_average) as recommendations_vote_average
,GROUP_CONCAT(recommendations.recommendations_title) as recommendations_title
FROM tmdb_movies ;

Returns

    movie_title recommendations_vote_average    recommendations_title
1   The Dark Knight 7.5,7.5,7.3,8.1,8,7.9,7.9,8,6.6,6.6 The Dark Knight Rises,Batman Begins,Iron Man,The Lord of the Rings: The Return of the King,The Lord of the Rings: The The Fellowship of the Ring,The Lord of the Rings: The Two Towers,The Matrix,Inception,Iron Man 2,Captain America: The First Avenger

http://rextester.com/NNJA85394


问:
Change the width of column in the Excel sheet via export in kendo
I'm using kendo grid in my ember app. I have introduced export to Excel in kendo. But after downloading the Excel sheet, I want to resize the width of the column within the Excel sheet .. how to deal with it?

Here is my code:

```<code>myGrid.bind("excelExport", function (e) {
    // console.log(">>"+);
    var str = e.sender.columns;
    var title = str.map(function(d) { return d['title']; }).indexOf('Action');
    var documentKey = str.map(function(d) { return d['field']; }).indexOf('documentKey');

    if (!exportFlag) {
        e.sender.hideColumn(documentKey);
        e.sender.hideColumn(title);
        e.preventDefault();

        exportFlag = true;

        setTimeout(function () {
            e.sender.saveAsExcel();
        });
    } else {
        e.sender.showColumn(documentKey);
        e.sender.showColumn(title);
        exportFlag = false;
    }
});
</code>```

答:
If you want to modify the format of cells during export to excel, you can setup a kendo.ooxml.Workbook.

This way you can modify the format of each cell, row, column etc by building up an array containing columns, rows and cells:

```<code>var workbook = new kendo.ooxml.Workbook({
  sheets: [
      {
          columns: [ { width: 100 }, { width: 200 } ],
          rows: [
            {
              cells: [
                { value: "this column is 100px" }, { value: "this column is 200px" }
              ]
            }
          ]
      }
  ]
});
</code>```

In your case you will need to build up the data you wish to send to the workbook based on what is in the grid datasource.

I have attached a Dojo example to demonstrate an example of all the above in action.

Body:
I'm using kendo grid in my ember app. I have introduced export to Excel in kendo. But after downloading the Excel sheet, I want to resize the width of the column within the Excel sheet .. how to deal with it?

Here is my code:

myGrid.bind("excelExport", function (e) {
    // console.log(">>"+);
    var str = e.sender.columns;
    var title = str.map(function(d) { return d['title']; }).indexOf('Action');
    var documentKey = str.map(function(d) { return d['field']; }).indexOf('documentKey');

    if (!exportFlag) {
        e.sender.hideColumn(documentKey);
        e.sender.hideColumn(title);
        e.preventDefault();

        exportFlag = true;

        setTimeout(function () {
            e.sender.saveAsExcel();
        });
    } else {
        e.sender.showColumn(documentKey);
        e.sender.showColumn(title);
        exportFlag = false;
    }
});

Body:
If you want to modify the format of cells during export to excel, you can setup a kendo.ooxml.Workbook.

This way you can modify the format of each cell, row, column etc by building up an array containing columns, rows and cells:

var workbook = new kendo.ooxml.Workbook({
  sheets: [
      {
          columns: [ { width: 100 }, { width: 200 } ],
          rows: [
            {
              cells: [
                { value: "this column is 100px" }, { value: "this column is 200px" }
              ]
            }
          ]
      }
  ]
});

In your case you will need to build up the data you wish to send to the workbook based on what is in the grid datasource.

I have attached a Dojo example to demonstrate an example of all the above in action.


问:
only writing the first row
i'm learning databases and my code doesn't return any error but it only writes the first row. Can you help me? By the way, the link is just an experiment :D
Code :
    page = urllib2.urlopen("https://en.wikipedia.org/wiki/Wushu_at_the_2014_Asian_Games_%E2%80%93_Men%27s_sanda_60_kg")
    soup = BeautifulSoup(page, "lxml")</p>

```<code>table = soup.find("table", class_="wikitable")

A = []
B = []
C = []

try:
    conn = psycopg2.connect("dbname='testdb' user='postgres' host='localhost' password='root'")
except:
    print 'Unable to connect to the database.'

cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

for row in table.findAll("tr"):
    cells = row.findAll("th")
    if len(cells) != 0:
        A.append(cells[0].find(text=True))
        B.append(cells[1].find(text=True))
        C.append(cells[2].find(text=True))
        cur.execute("""INSERT INTO test(event_date,event_time,event_event)
VALUES(%s,%s,%s)""", (A,B,C))
        conn.commit()
</code>```

答:
Make sure your

```<code>if len(cells) != 0:
</code>```

condition is true for your expectation.

Also you should call

```<code>del A[:]
del B[:]
del C[:]
</code>```

after the conn.commit() line

Title: only writing the first row

Body:
i'm learning databases and my code doesn't return any error but it only writes the first row. Can you help me? By the way, the link is just an experiment :D
Code :
    page = urllib2.urlopen("https://en.wikipedia.org/wiki/Wushu_at_the_2014_Asian_Games_%E2%80%93_Men%27s_sanda_60_kg")
    soup = BeautifulSoup(page, "lxml")

table = soup.find("table", class_="wikitable")

A = []
B = []
C = []

try:
    conn = psycopg2.connect("dbname='testdb' user='postgres' host='localhost' password='root'")
except:
    print 'Unable to connect to the database.'

cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

for row in table.findAll("tr"):
    cells = row.findAll("th")
    if len(cells) != 0:
        A.append(cells[0].find(text=True))
        B.append(cells[1].find(text=True))
        C.append(cells[2].find(text=True))
        cur.execute("""INSERT INTO test(event_date,event_time,event_event)
VALUES(%s,%s,%s)""", (A,B,C))
        conn.commit()

Body:
Make sure your

if len(cells) != 0:

condition is true for your expectation.

Also you should call

del A[:]
del B[:]
del C[:]

after the conn.commit() line


问:
Indexing and searching related objects with haystack
I'm pretty new to search implementation, bear with me while I'm learning!

So my pet project is a recipe site and each recipe can have n steps. the model looks something like:

```<code>class Recipe(models.Model):
    title = models.CharField(max_length=255)
    description = models.TextField()
    hotness = models.ForeignKey(Hotness)
    recipe_diet = models.ManyToManyField(DietType)
    ingredients = models.ManyToManyField(Ingredient, through="RecipeIngredient")

class DietType(models.Model):
    diet_type = models.CharField(max_length=50)
    description = models.TextField(null=True, blank=True)

class RecipeIngredient(models.Model):
    recipe = models.ForeignKey(Recipe)
    ingredient = models.ForeignKey(Ingredient)
    quantifier = models.ForeignKey(Quantifier)
    quantity = models.FloatField()

class RecipeSteps(models.Model):
    step_number = models.IntegerField()
    description = models.TextField()
    recipe = models.ForeignKey(Recipe)
</code>```

(shortened for brevity)

I want to index all of it: Recipe, RecipeIngredient, DietType and Steps...
The DietType and RecipeIngredient seem to be working fine, but the Steps are not. I assume this has to do with the usage of 'RelatedSearchQuerySet' ?

Here is my search_indexes.py:

```<code>from haystack import indexes
from recipes.models import Recipe

class RecipeIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    title = indexes.CharField(model_attr='title')
    ingredients = indexes.MultiValueField(indexed=True, stored=True)
    description = indexes.CharField(model_attr='description')
    hotness = indexes.CharField(model_attr='hotness')
    diet_type = indexes.MultiValueField(indexed=True, stored=True)
    recipesteps = indexes.MultiValueField(indexed=True, stored=True)

    def prepare_steps(self, object):
        return [step.description for step in object.recipesteps.all()]

    def get_model(self):
        return Recipe

    def load_all_queryset(self):
        # Pull all objects related to the Note in search results.
        return Recipe.objects.all().select_related()
</code>```

Here is the template recipe_text.txt:

```<code>{{ object.title }}
{{ object.cuisine }}
{% for ingr in object.ingredients.all %}
  {{ ingr.title }}
{% endfor %}
{{ object.description }}
{% for dt in object.recipe_diet.all %}
  {{ dt.diet_type }}
{% endfor %}
{{ object.user }}
{{ object.hotness }}
{% for step in object.recipesteps.all %}
  {{ step.description }}
{% endfor %}
{{ object.body }}
</code>```

I can search ingredients, title, description, diet type - everything works, except the RecipeSteps.

Finally, I'm making queries through the shell only at the moment:

```<code>#producing results:
sq = SearchQuerySet().filter(content='onion') #ingredient
sq = SearchQuerySet().filter(content='bolognese') #title
sq = SearchQuerySet().filter(content='bologna') #description
#not producing any results:
sq = SearchQuerySet().filter(content='chop') #step
sq = RelatedSearchQuerySet().filter(content='chop').load_all() #assuming this does the expanded search
</code>```

Any idea?

答:
I have identified two issues:

The name prepare_steps in your RecipeIndex is wrong it should be prepare_{field_name} so change it to prepare_recipesteps

You are trying to access related steps object.recipesteps.all objects recipe_text.txt in a wrong way, it should be object.recipesteps_set.all. Or keep using recipesteps but add this as a related_name in RecipeSteps model for ForeignKey Recipe e.g.

```<code>class RecipeSteps(models.Model):
    # //
    recipe = models.ForeignKey(Recipe, related_name='recipesteps')
</code>```

Body:
I'm pretty new to search implementation, bear with me while I'm learning!

So my pet project is a recipe site and each recipe can have n steps. the model looks something like:

class Recipe(models.Model):
    title = models.CharField(max_length=255)
    description = models.TextField()
    hotness = models.ForeignKey(Hotness)
    recipe_diet = models.ManyToManyField(DietType)
    ingredients = models.ManyToManyField(Ingredient, through="RecipeIngredient")

class DietType(models.Model):
    diet_type = models.CharField(max_length=50)
    description = models.TextField(null=True, blank=True)

class RecipeIngredient(models.Model):
    recipe = models.ForeignKey(Recipe)
    ingredient = models.ForeignKey(Ingredient)
    quantifier = models.ForeignKey(Quantifier)
    quantity = models.FloatField()

class RecipeSteps(models.Model):
    step_number = models.IntegerField()
    description = models.TextField()
    recipe = models.ForeignKey(Recipe)

(shortened for brevity)

I want to index all of it: Recipe, RecipeIngredient, DietType and Steps...
The DietType and RecipeIngredient seem to be working fine, but the Steps are not. I assume this has to do with the usage of 'RelatedSearchQuerySet' ?

Here is my search_indexes.py:

from haystack import indexes
from recipes.models import Recipe

class RecipeIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    title = indexes.CharField(model_attr='title')
    ingredients = indexes.MultiValueField(indexed=True, stored=True)
    description = indexes.CharField(model_attr='description')
    hotness = indexes.CharField(model_attr='hotness')
    diet_type = indexes.MultiValueField(indexed=True, stored=True)
    recipesteps = indexes.MultiValueField(indexed=True, stored=True)

    def prepare_steps(self, object):
        return [step.description for step in object.recipesteps.all()]

    def get_model(self):
        return Recipe

    def load_all_queryset(self):
        # Pull all objects related to the Note in search results.
        return Recipe.objects.all().select_related()

Here is the template recipe_text.txt:

{{ object.title }}
{{ object.cuisine }}
{% for ingr in object.ingredients.all %}
  {{ ingr.title }}
{% endfor %}
{{ object.description }}
{% for dt in object.recipe_diet.all %}
  {{ dt.diet_type }}
{% endfor %}
{{ object.user }}
{{ object.hotness }}
{% for step in object.recipesteps.all %}
  {{ step.description }}
{% endfor %}
{{ object.body }}

I can search ingredients, title, description, diet type - everything works, except the RecipeSteps.

Finally, I'm making queries through the shell only at the moment:

#producing results:
sq = SearchQuerySet().filter(content='onion') #ingredient
sq = SearchQuerySet().filter(content='bolognese') #title
sq = SearchQuerySet().filter(content='bologna') #description
#not producing any results:
sq = SearchQuerySet().filter(content='chop') #step
sq = RelatedSearchQuerySet().filter(content='chop').load_all() #assuming this does the expanded search

Any idea?

Body:
I have identified two issues:

The name prepare_steps in your RecipeIndex is wrong it should be prepare_{field_name} so change it to prepare_recipesteps

You are trying to access related steps object.recipesteps.all objects recipe_text.txt in a wrong way, it should be object.recipesteps_set.all. Or keep using recipesteps but add this as a related_name in RecipeSteps model for ForeignKey Recipe e.g.

class RecipeSteps(models.Model):
    # //
    recipe = models.ForeignKey(Recipe, related_name='recipesteps')


问:
Strange behavior with TableView separator when also using TableFooterView and row actions
Here is a basic tableview that I have set up with a tableviewcontroller. The reuse identifier just gets a light green prototype cell.

```<code>#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib
    self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 25)];
    [self.tableView.tableFooterView setBackgroundColor:[UIColor colorWithRed:215/255 green:1 blue:1 alpha:1]];
}

- (BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewRowAction *removeFolderRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault
                                                                                title:@"hi"
                                                                               handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
                                               {
                                                   return;
                                               }];

    return @[removeFolderRowAction];
}

- (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    return;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 4;
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [self.tableView dequeueReusableCellWithIdentifier:@"cell"];
}

@end
</code>```

This produces this flow:

where it starts with no bottom separator, then if you go to editing mode on the last cell there is still no bottom separator, but when done editing, a full width separator appears, which leaves if you go to editing mode again. If I were to have my tableFooterView be a view with frame CGRectZero, it would behave in the expected manner (there is a separator, same as all the other ones, that doesn't move when going to edit mode), however as soon as the tableFooterView has some height, it goes back to acting like the pictures above.

答:
So i digged a bit and ios 11 fixed this issue for me. Seems to be a bug in previous versions.
For me the separator would show in the last rows that touch a header or a footer</p>

Body:
Here is a basic tableview that I have set up with a tableviewcontroller. The reuse identifier just gets a light green prototype cell.

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib
    self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 25)];
    [self.tableView.tableFooterView setBackgroundColor:[UIColor colorWithRed:215/255 green:1 blue:1 alpha:1]];
}

- (BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewRowAction *removeFolderRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault
                                                                                title:@"hi"
                                                                               handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
                                               {
                                                   return;
                                               }];

    return @[removeFolderRowAction];
}

- (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    return;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 4;
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [self.tableView dequeueReusableCellWithIdentifier:@"cell"];
}

@end

This produces this flow:

where it starts with no bottom separator, then if you go to editing mode on the last cell there is still no bottom separator, but when done editing, a full width separator appears, which leaves if you go to editing mode again. If I were to have my tableFooterView be a view with frame CGRectZero, it would behave in the expected manner (there is a separator, same as all the other ones, that doesn't move when going to edit mode), however as soon as the tableFooterView has some height, it goes back to acting like the pictures above.


问:
Header Footer and content
I already create view : header, content, and footer but footer and content not display and not getting an error. the directory in form1.view.xml is correct because no error when I load the form1 view. when I command the header code and I refresh, the content show and footer still not show. when I command the header and content, the footer show. how to fix this problem?

Form1.view.xml

```<code><App id="navCon"
    class="footer-height footer-color header-color background-home background-color
                            footer-size-color panel-header">

    <!-- Header -->
    <mvc:XMLView viewName="sap.ui.taspen.taspen.Header" />

    <App>
        <pages>
            <Page>
                <Panel id="panelModule" headerText="Header form" class="panelForm">
                    <content>
                        <Label text="Ini form 1" />
                    </content>
                </Panel>
            </Page>
        </pages>
    </App>

    <!-- Footer -->
    <mvc:XMLView viewName="sap.ui.taspen.taspen.Footer" />
</App>
</code>```

Header:

```<code><mvc:View xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m" xmlns:t="sap.ui.table" xmlns:l="sap.ui.layout" xmlns:tnt="sap.tnt"
    controllerName="sap.ui.taspen.taspen.Header" xmlns:html="http://www.w3.org/1999/xhtml">
    <App>
        <pages>
            <Page showHeader="false">
                <tnt:ToolHeader>
                    <html:img src="icon/logo_taspen.png" class="header-logo-taspen" />
                    <html:p class="text-header">NEW APPLICATION CORE BUSINESS</html:p>
                    <ToolbarSpacer width="20px" />

                    <tnt:ToolHeaderUtilitySeparator />
                    <ToolbarSpacer>
                        <layoutData>
                            <OverflowToolbarLayoutData priority="NeverOverflow"
                                minWidth="20px" />
                        </layoutData>
                    </ToolbarSpacer>

                    <Text text="Selasa, 21/4/2017 / 11:07 AM" class="text-white" />
                    <Text text="Hello, Jhon Doe" class="text-white">
                        <layoutData>
                            <OverflowToolbarLayoutData priority="NeverOverflow" />
                        </layoutData>
                    </Text>

                    <Button icon="sap-icon://log" type="Reject" press="logoutPress"
                        class="button-logout button-logout-icon margin-logout">
                        <layoutData>
                            <OverflowToolbarLayoutData priority="NeverOverflow" />
                        </layoutData>
                    </Button>
                </tnt:ToolHeader>
            </Page>
        </pages>
    </App>
</mvc:View>
</code>```

Footer:

```<code><mvc:View xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m" xmlns:t="sap.ui.table" xmlns:l="sap.ui.layout" xmlns:tnt="sap.tnt"
    controllerName="sap.ui.taspen.taspen.Footer" xmlns:html="http://www.w3.org/1999/xhtml">
    <App>
        <Page showHeader="false">
            <footer>
                <OverflowToolbar id="otbFooter">
                    <Button type="Transparent" text="Kebijakan dan Privasi"
                        press="kebdanprivPress" />
                    <Button type="Transparent" text="Bantuan" press="bantuanPress" />
                    <ToolbarSpacer />
                    <Label text="All Rights Reserved PT. Taspen Persero" />
                    <html:img src="icon/copyright-symbol.png" class="footer-logo-copyright" />
                    <Label text="2018" />
                </OverflowToolbar>
            </footer>
        </Page>
    </App>
</mvc:View>
</code>```

答:
To Display custome header instead of page header you have to use

```<code><customHeader></customHeader>
</code>```

tag.and remaining you have to place in <content></content>tag. can see you are missing content tag.

ContentLicense: CC BY-SA 4.0

Title: Header Footer and content

Body:
I already create view : header, content, and footer but footer and content not display and not getting an error. the directory in form1.view.xml is correct because no error when I load the form1 view. when I command the header code and I refresh, the content show and footer still not show. when I command the header and content, the footer show. how to fix this problem?

Form1.view.xml

<App id="navCon"
    class="footer-height footer-color header-color background-home background-color
                            footer-size-color panel-header">

    <mvc:XMLView viewName="sap.ui.taspen.taspen.Header" />

    <App>
        <pages>
            <Page>
                <Panel id="panelModule" headerText="Header form" class="panelForm">
                    <content>

                    </content>
                </Panel>
            </Page>
        </pages>
    </App>

    <mvc:XMLView viewName="sap.ui.taspen.taspen.Footer" />
</App>

Header:

<mvc:View xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m" xmlns:t="sap.ui.table" xmlns:l="sap.ui.layout" xmlns:tnt="sap.tnt"
    controllerName="sap.ui.taspen.taspen.Header" xmlns:html="http://www.w3.org/1999/xhtml">
    <App>
        <pages>
            <Page showHeader="false">
                <tnt:ToolHeader>

                    NEW APPLICATION CORE BUSINESS
                    <ToolbarSpacer width="20px" />

                    <tnt:ToolHeaderUtilitySeparator />
                    <ToolbarSpacer>
                        <layoutData>
                            <OverflowToolbarLayoutData priority="NeverOverflow"
                                minWidth="20px" />
                        </layoutData>
                    </ToolbarSpacer>

                    <Text text="Selasa, 21/4/2017 / 11:07 AM" class="text-white" />
                    <Text text="Hello, Jhon Doe" class="text-white">
                        <layoutData>
                            <OverflowToolbarLayoutData priority="NeverOverflow" />
                        </layoutData>
                    </Text>

                    <Button icon="sap-icon://log" type="Reject" press="logoutPress"
                        class="button-logout button-logout-icon margin-logout">
                        <layoutData>
                            <OverflowToolbarLayoutData priority="NeverOverflow" />
                        </layoutData>
                    </Button>
                </tnt:ToolHeader>
            </Page>
        </pages>
    </App>
</mvc:View>

Footer:

<mvc:View xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m" xmlns:t="sap.ui.table" xmlns:l="sap.ui.layout" xmlns:tnt="sap.tnt"
    controllerName="sap.ui.taspen.taspen.Footer" xmlns:html="http://www.w3.org/1999/xhtml">
    <App>
        <Page showHeader="false">

                <OverflowToolbar id="otbFooter">
                    <Button type="Transparent" text="Kebijakan dan Privasi"
                        press="kebdanprivPress" />
                    <Button type="Transparent" text="Bantuan" press="bantuanPress" />
                    <ToolbarSpacer />

                </OverflowToolbar>

        </Page>
    </App>
</mvc:View>

Body:
To Display custome header instead of page header you have to use

<customHeader></customHeader>

tag.and remaining you have to place in <content></content>tag. can see you are missing content tag.


答: Perhaps use console.log(JSON.stringify(array)) to make that happen

Title: Initialization and pushing data in array

Body:
First, I declare an array :

let arr = [];

Hence, I fill this array in the following way :

(async function loop() {
        for(let i=timeStart; i<=timeEnd; i+=3600000)
        {
          await ExternDataProvider.getCountData(i, (i+3600000), localSearchFilters)
            .then(function(dataResult){
              arr.push(dataResult);
            })
            .catch(function(err){
            });
        }
      })();

But, when I make a console.log of the variable "arr", I have the following result :

So why I dont have something like [2251,215] instead ?


问:
My C# grading program keep outputting the same result
I just started C# and was making this very simple C# program to print a grade according to the inputed marks.

Here's my program:

```<code>    class data
{

    int marks;
    public void input()
    {
        Console.WriteLine("Enter your marks");
        marks = Convert.ToInt16(Console.ReadLine());

    }

    public void output()
    {
        if (marks >= 75)
        {
            Console.WriteLine("Merit");
        }
        else if (marks < 75)
        {
            Console.WriteLine("Distiction");
        }
        else if (marks < 65)
        {
            Console.WriteLine("Credit");
        }
        else if (marks < 55)
        {
            Console.WriteLine("Pass");
        }
        else Console.WriteLine("Fail");

    }
}
}
</code>```

And here's the main:

```<code> class Program
{
    static void Main(string[] args)
    {
        data obj1 = new data();
        obj1.input();
        obj1.output();
        Console.ReadLine();

    }
}
}
</code>```

Problem is it keeps outputting "Distinction" as the grade no matter what input I give. What am I doing wrong?

Edit - Fail marks is below 40

答:
I guess this is what you have expected:

```<code>public void output()
{
    if (marks >= 75)
    {
        Console.WriteLine("Merit");
    }
    else if (marks < 55)
    {
        Console.WriteLine("Pass");
    }
    else if (marks < 65)
    {
        Console.WriteLine("Credit");
    }
    else if (marks < 75)
    {
        Console.WriteLine("Distiction");
    }
    else Console.WriteLine("Fail");
}
</code>```

P.S. Please begin classes and methods names with an uppercase.

Body:
I just started C# and was making this very simple C# program to print a grade according to the inputed marks.

Here's my program:

    class data
{

    int marks;
    public void input()
    {
        Console.WriteLine("Enter your marks");
        marks = Convert.ToInt16(Console.ReadLine());

    }

    public void output()
    {
        if (marks >= 75)
        {
            Console.WriteLine("Merit");
        }
        else if (marks < 75)
        {
            Console.WriteLine("Distiction");
        }
        else if (marks < 65)
        {
            Console.WriteLine("Credit");
        }
        else if (marks < 55)
        {
            Console.WriteLine("Pass");
        }
        else Console.WriteLine("Fail");

    }
}
}

And here's the main:

 class Program
{
    static void Main(string[] args)
    {
        data obj1 = new data();
        obj1.input();
        obj1.output();
        Console.ReadLine();

    }
}
}

Problem is it keeps outputting "Distinction" as the grade no matter what input I give. What am I doing wrong?

Edit - Fail marks is below 40

Body:
I guess this is what you have expected:

public void output()
{
    if (marks >= 75)
    {
        Console.WriteLine("Merit");
    }
    else if (marks < 55)
    {
        Console.WriteLine("Pass");
    }
    else if (marks < 65)
    {
        Console.WriteLine("Credit");
    }
    else if (marks < 75)
    {
        Console.WriteLine("Distiction");
    }
    else Console.WriteLine("Fail");
}

P.S. Please begin classes and methods names with an uppercase.


问:
Mouse over Popup on multiple markers leaflet.js?
so I have a leaflet map with lot of markers placed on it. I want to have a popup with like the status of asset etc on 'hover' over the marker. I see some examples on google and try to implement but none of them is firing any events.  here is my code with my attempt. how can i achieve this feature? do i have to use somekind of tooltip instead of popup?

```<code>  buildMarkerLayer = (rawAssetsObjects) => {
    let markersGroup = null;
    var self = this;

    markersGroup = L.markerClusterGroup({
        spiderfyOnMaxZoom: true,
        showCoverageOnHover: true,
        zoomToBoundsOnClick: true,
        spiderfyDistanceMultiplier: 2
    });

      self.$localForage.getItem('showAllAreas').then((_showAll) => {
        if(_showAll){
            this.loadAllAreas();
        }else{
            this.hideAllAreas();
        }

    });

    angular.forEach(rawAssetsObjects, function(_asset) {

        if(_asset.latitude && _asset.longitude){
            markersGroup.addLayer(L.marker(L.latLng(_asset.latitude,
            _asset.longitude), {
            id: _asset.id,
            icon: L.divIcon({
                html: self.siMarkers.createHTMLMarker(_asset)
            })
            }).on('click', function(e) {
                //dismiss the event timeline
                self.$mdSidenav('right').close();

                self.centerOnClick(_asset);
                //set the selected asset to a shared service for availability in
                //other controllers
                self.siMapRam.setActive(_asset);
                //inform detail controller of a newly selected asset to query
                self.$rootScope.$broadcast('ActiveAssetChange');
                self.dgModal.display();
            }).bindPopup('work').on('mouseover',function(ev) {
               markersGroup.openPopup();
}));
        };
    });

    return markersGroup
}
</code>```

so I added the mouseover function and is responding on the console with error, so at least i know the listening part is working

答:
I was close to the answer, while following many examples on google they made L.Marker into a variable like var marker = L.marker. Then call marker.openPopup(). My case, as you can see, I straight called L.marker. Problem was calling L.marker.openPopup() or L.marker(openPopup()) throws error saying openPopup is undefined. so the solution was pretty straight forward and make L.marker into a variable. like below. I also added small popup formatting like where pop-up should display using popAnchor and HTML formatting, for future flowers

```<code>angular.forEach(rawAssetsObjects, function (_asset) {

          let marker =  L.marker(L.latLng(_asset.latitude,
                  _asset.longitude), {
                      id: _asset.id,
                      icon: L.divIcon({
                          html: self.siMarkers.createHTMLMarker(_asset),
                          popupAnchor: [0,-80]
                      })

                  });

          if (_asset.latitude && _asset.longitude) {
              let content = "<b>"+_asset.name+"</b>"+"<br>"+"<b>"+'Status: '+"</b>"+_asset.status
              markersGroup.addLayer( marker.bindPopup(content)
                     .on('mouseover', function (e) {
                      self.siMapRam.setActive(_asset);
                      self.$rootScope.$broadcast('ActiveAssetChange');
                      marker.openPopup()

                  })
                  .on('click', function (e) {
                      //dismiss the event timeline
                      self.$mdSidenav('right').close();
                      self.centerOnClick(_asset);
                      //set the selected asset to a shared service for availability in
                      //other controllers
                      self.siMapRam.setActive(_asset);
                      //inform detail controller of a newly selected asset to query
                      self.$rootScope.$broadcast('ActiveAssetChange');
                      self.dgModal.display();
                  }));
          };
      });

    return markersGroup
}
</code>```

Body:
so I have a leaflet map with lot of markers placed on it. I want to have a popup with like the status of asset etc on 'hover' over the marker. I see some examples on google and try to implement but none of them is firing any events.  here is my code with my attempt. how can i achieve this feature? do i have to use somekind of tooltip instead of popup?

  buildMarkerLayer = (rawAssetsObjects) => {
    let markersGroup = null;
    var self = this;

    markersGroup = L.markerClusterGroup({
        spiderfyOnMaxZoom: true,
        showCoverageOnHover: true,
        zoomToBoundsOnClick: true,
        spiderfyDistanceMultiplier: 2
    });

      self.$localForage.getItem('showAllAreas').then((_showAll) => {
        if(_showAll){
            this.loadAllAreas();
        }else{
            this.hideAllAreas();
        }

    });

    angular.forEach(rawAssetsObjects, function(_asset) {

        if(_asset.latitude && _asset.longitude){
            markersGroup.addLayer(L.marker(L.latLng(_asset.latitude,
            _asset.longitude), {
            id: _asset.id,
            icon: L.divIcon({
                html: self.siMarkers.createHTMLMarker(_asset)
            })
            }).on('click', function(e) {
                //dismiss the event timeline
                self.$mdSidenav('right').close();

                self.centerOnClick(_asset);
                //set the selected asset to a shared service for availability in
                //other controllers
                self.siMapRam.setActive(_asset);
                //inform detail controller of a newly selected asset to query
                self.$rootScope.$broadcast('ActiveAssetChange');
                self.dgModal.display();
            }).bindPopup('work').on('mouseover',function(ev) {
               markersGroup.openPopup();
}));
        };
    });

    return markersGroup
}

so I added the mouseover function and is responding on the console with error, so at least i know the listening part is working

Body:
I was close to the answer, while following many examples on google they made L.Marker into a variable like var marker = L.marker. Then call marker.openPopup(). My case, as you can see, I straight called L.marker. Problem was calling L.marker.openPopup() or L.marker(openPopup()) throws error saying openPopup is undefined. so the solution was pretty straight forward and make L.marker into a variable. like below. I also added small popup formatting like where pop-up should display using popAnchor and HTML formatting, for future flowers

angular.forEach(rawAssetsObjects, function (_asset) {

          let marker =  L.marker(L.latLng(_asset.latitude,
                  _asset.longitude), {
                      id: _asset.id,
                      icon: L.divIcon({
                          html: self.siMarkers.createHTMLMarker(_asset),
                          popupAnchor: [0,-80]
                      })

                  });

          if (_asset.latitude && _asset.longitude) {
              let content = "<b>"+_asset.name+"</b>"+"<br>"+"<b>"+'Status: '+"</b>"+_asset.status
              markersGroup.addLayer( marker.bindPopup(content)
                     .on('mouseover', function (e) {
                      self.siMapRam.setActive(_asset);
                      self.$rootScope.$broadcast('ActiveAssetChange');
                      marker.openPopup()

                  })
                  .on('click', function (e) {
                      //dismiss the event timeline
                      self.$mdSidenav('right').close();
                      self.centerOnClick(_asset);
                      //set the selected asset to a shared service for availability in
                      //other controllers
                      self.siMapRam.setActive(_asset);
                      //inform detail controller of a newly selected asset to query
                      self.$rootScope.$broadcast('ActiveAssetChange');
                      self.dgModal.display();
                  }));
          };
      });

    return markersGroup
}


问:
Visual Studio 2017 Xamarin Android API Level 25: Enable the default proguard
I cannot build my android application with the default visual studio 2017 proguard enabled.

I enable the proguard from

Project > Android.Properties > Android Options > Check "Enable ProGuard"

Then I cannot build my application.

It says:

C:\Program Files (Access is denied)

How do I fix this?

答:
Try the following I had a similar issue and work for me:
-dontwarn okio.**
-dontwarn java.nio.**
-dontwarn java.lang.invoke.**
The conversation about the same issue was continued here with other solutions:
https://forums.xamarin.com/discussion/45210/enable-proguard-error-c-program-files-access-is-denied</p>


问:
How to display all the values from one table but on two columns in that table, display the value of other tables if their column name is the same
I have a table that I will get all the values from.

```<code>CREATE TABLE [dbo].[DiagnosticLog]
(
    [DiagnosticLogID]   [int]       NOT NULL identity(-2147483648,1),
    [ServerID]          [int]       NOT NULL, --changed to int for now
    [MessageID]         [smallint]      NOT NULL,
    [Something]         [bigint]        NOT NULL,
    [SomethingElse]         [varchar](100)  NOT NULL,
    [CreateDate]            [smalldatetime] NOT NULL
)
</code>```

I want to replace the MessageID in the first table with the MessageDescription in the second table when the value of the MessageID in the tables are the same.

```<code>CREATE TABLE [dbo].[Message]
(
              [MessageID]     [smallint]     IDENTITY(1,1) NOT NULL,
              [MessageDescription]    [varchar](100)   NOT NULL,
              [CreateDate]     [datetime]    NOT NULL
)
</code>```

same with the ServerID column. The value of ServerID column from the first table will be the value of ServerName when the value of the ServerID's are the same.

```<code>CREATE TABLE [dbo].[Server]
(
    [ServerID]          [smallint]      NOT NULL identity(1,1),
    [ServerName]            [char](20)      NOT NULL,
    [ServerPort]            [int]           NOT NULL,
    [ServerIP]              [char](20)      NOT NULL,
    [CacheType]             [char](10)      NOT NULL,
    [CreateDate]            [datetime]      NOT NULL
)
</code>```

If I do this query I can get some of the information I want but I want the Message Description to replace MessageId.

```<code>SELECT * from DiagnosticLog INNER JOIN  Message  on DiagnosticLog.EBCPMessageID = Message.MessageID
</code>```

Also, I'm learning about indexing for SQL. What would be a good way for me to make indexes on the tables so it queries faster? Would I create an index on MessageID and ServerID?

答:
I am assuming you want a query, not to actually update any values. You can do this with a left join to each of the referenced tables and using isnull() to determine if there is a corresponding value, and if not, use the ID:

```<code>select
    dl.DiagnosticLogID
  , ServerID  = isnull(s.ServerName,convert(char(20),dl.ServerID))
  , MessageID = isnull(m.MessageDescription,convert(varchar(100),dl.MessageID))
  , dl.Something
  , dl.SomethingElse
  , dl.CreateDate
from dbo.DiagnosticLog dl
  left join dbo.Message m
    on dl.MessageID = m.MessageID
  left join dbo.Server s
    on dl.ServerID = s.ServerID
</code>```

You say 'when the value of MessageID is the same', so I have used left joins. If there will always be a corresponding row, you can use inner joins instead, and you would not need to account for null values:

```<code>select
    dl.DiagnosticLogID
  , ServerID  = s.ServerName
  , MessageID = m.MessageDescription
  , dl.Something
  , dl.SomethingElse
  , dl.CreateDate
from dbo.DiagnosticLog dl
  inner join dbo.Message m
    on dl.MessageID = m.MessageID
  inner join dbo.Server s
    on dl.ServerID = s.ServerID
</code>```

Body:
I have a table that I will get all the values from.

CREATE TABLE [dbo].[DiagnosticLog]
(
    [DiagnosticLogID]   [int]       NOT NULL identity(-2147483648,1),
    [ServerID]          [int]       NOT NULL, --changed to int for now
    [MessageID]         [smallint]      NOT NULL,
    [Something]         [bigint]        NOT NULL,
    [SomethingElse]         [varchar](100)  NOT NULL,
    [CreateDate]            [smalldatetime] NOT NULL
)

I want to replace the MessageID in the first table with the MessageDescription in the second table when the value of the MessageID in the tables are the same.

CREATE TABLE [dbo].[Message]
(
              [MessageID]     [smallint]     IDENTITY(1,1) NOT NULL,
              [MessageDescription]    [varchar](100)   NOT NULL,
              [CreateDate]     [datetime]    NOT NULL
)

same with the ServerID column. The value of ServerID column from the first table will be the value of ServerName when the value of the ServerID's are the same.

CREATE TABLE [dbo].[Server]
(
    [ServerID]          [smallint]      NOT NULL identity(1,1),
    [ServerName]            [char](20)      NOT NULL,
    [ServerPort]            [int]           NOT NULL,
    [ServerIP]              [char](20)      NOT NULL,
    [CacheType]             [char](10)      NOT NULL,
    [CreateDate]            [datetime]      NOT NULL
)

If I do this query I can get some of the information I want but I want the Message Description to replace MessageId.

SELECT * from DiagnosticLog INNER JOIN  Message  on DiagnosticLog.EBCPMessageID = Message.MessageID

Also, I'm learning about indexing for SQL. What would be a good way for me to make indexes on the tables so it queries faster? Would I create an index on MessageID and ServerID?

Body:
I am assuming you want a query, not to actually update any values. You can do this with a left join to each of the referenced tables and using isnull() to determine if there is a corresponding value, and if not, use the ID:

select
    dl.DiagnosticLogID
  , ServerID  = isnull(s.ServerName,convert(char(20),dl.ServerID))
  , MessageID = isnull(m.MessageDescription,convert(varchar(100),dl.MessageID))
  , dl.Something
  , dl.SomethingElse
  , dl.CreateDate
from dbo.DiagnosticLog dl
  left join dbo.Message m
    on dl.MessageID = m.MessageID
  left join dbo.Server s
    on dl.ServerID = s.ServerID

You say 'when the value of MessageID is the same', so I have used left joins. If there will always be a corresponding row, you can use inner joins instead, and you would not need to account for null values:

select
    dl.DiagnosticLogID
  , ServerID  = s.ServerName
  , MessageID = m.MessageDescription
  , dl.Something
  , dl.SomethingElse
  , dl.CreateDate
from dbo.DiagnosticLog dl
  inner join dbo.Message m
    on dl.MessageID = m.MessageID
  inner join dbo.Server s
    on dl.ServerID = s.ServerID


问:
java.lang.IllegalStateException: missing behavior definition for the preceding method call getLast(...)
I've already read similar questions on SO like this, but I can't solve my problem.
I've modified an existing class and when I try to build it with ant I get the following unit test failed error:

java.lang.IllegalStateException: missing behavior definition for the preceding method call getLast(class mypackage.model.MyObj, 1)
      at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:43)
      at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:73)
      at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:92)
      at mypackage.service.MyService$$EnhancerByCGLIB$$347f5838.getLast()
      at mypackage.controller.MyController.myControllerMethod(MyController.java:265)
      at mypackage.controller.MyController.myControllerMethodTest(MyControllerTest.java:207)

In MyController.java I've added a piece of code like (the error is at line 265):

```<code>263. public void myControllerMethod(Integer id) {
264.   String myString = null;
265.   MyObj myObj = (MyObj) myService.getLast(MyObj.class, id);
266.   try {
267.     myString = myObj.getMyProp().getMyObj();
268.   } catch (Exception e) {
269.     myString = "";
270.   }
</code>```

MyControllerTest.java simply calls myControllerMethod, like:

```<code>207. myController.myControllerMethod(1);
</code>```

I've already tried to add an "expectation" before the line 207, like:

```<code>206. EasyMock.expect(myServiceMock.getLast(MyObj.class, 1));
</code>```

rather than:

```<code>206. EasyMock.expect(myServiceMock.getLast(MyObj.class, 1)).andReturn(new MyObj());
</code>```

But to no avail.
Can anyone help me, please?

答:
Ok, I solved with EasyMock.replay(myServiceMock) as I found in this example.

That's a kind of "activation" of the expectation inserted before.

Body:
I've already read similar questions on SO like this, but I can't solve my problem.
I've modified an existing class and when I try to build it with ant I get the following unit test failed error:

java.lang.IllegalStateException: missing behavior definition for the preceding method call getLast(class mypackage.model.MyObj, 1)
      at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:43)
      at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:73)
      at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:92)
      at mypackage.service.MyService$$EnhancerByCGLIB$$347f5838.getLast()
      at mypackage.controller.MyController.myControllerMethod(MyController.java:265)
      at mypackage.controller.MyController.myControllerMethodTest(MyControllerTest.java:207)

In MyController.java I've added a piece of code like (the error is at line 265):

263. public void myControllerMethod(Integer id) {
264.   String myString = null;
265.   MyObj myObj = (MyObj) myService.getLast(MyObj.class, id);
266.   try {
267.     myString = myObj.getMyProp().getMyObj();
268.   } catch (Exception e) {
269.     myString = "";
270.   }

MyControllerTest.java simply calls myControllerMethod, like:

207. myController.myControllerMethod(1);

I've already tried to add an "expectation" before the line 207, like:

206. EasyMock.expect(myServiceMock.getLast(MyObj.class, 1));

rather than:

206. EasyMock.expect(myServiceMock.getLast(MyObj.class, 1)).andReturn(new MyObj());

But to no avail.
Can anyone help me, please?